I am trying to set a value for a 2 parameters in SQL:
#DateLoading
#DateLoading2
I declare them as datetime:
DECLARE #DateLoading AS datetime
DELCARE #DateLoading2 AS datetime
In the WHERE clause I set the parameters as following:
WHERE
o.DateLoading >= #Datetoloading AND
o.DateLoading < #Datetoloading2 AND
I have problem setting the scalar value. I've tried with this code, but the error is the same:
SET #DateLoading = COALESCE(CASE WHEN #DateLoading = 'Current Month' THEN DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0) ELSE NULL END,
CASE WHEN #DateLoading = 'Previous Month' THEN DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 1, 0) ELSE NULL END,
CASE WHEN #DateLoading = 'Previous 7 Days' THEN DATEADD(HOUR, 6, DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()) - 1, 0)) ELSE NULL END,
DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)
);
SET #DateLoading2 = COALESCE(
CASE WHEN #DateLoading2= 'Current Month' THEN DATEADD(DAY,DATEDIFF(DAY,0,GETDATE()),0) ELSE NULL END,
CASE WHEN #DateLoading2= 'Previous Month' THEN DATEADD(MONTH,DATEDIFF(MONTH,0,GETDATE()),0) ELSE NULL END,
CASE WHEN #DateLoading2= 'Previous 7 Days' THEN DATEADD(HOUR,6,DATEADD(DAY,DATEDIFF(DAY,0,GETDATE()),0)) ELSE NULL END,
GETDATE()
)
Here is the error messages:
Msg 137, Level 15, State 2, Line 6
Must declare the scalar variable "#TimePeriod".
Msg 102, Level 15, State 1, Line 16
Incorrect syntax near 'E'
Yes, you were right. I got rid of [S, [E]... (I wanted them to be alias) but I got rid of them... Also, the second mistake was #TimePeriod... I changed it to #DateLoading... But now, there is only 1 error message:
Conversion failed when converting data and/or time from character string
The client should enter Start Date and End Date so as to receive results. But the code I have for setting the scalar value for these two parameters is totally wrong.
I am trying to find the difference between two dates in SQL but ignoring weekends...
I've tried looking at other answers and keep getting the error:
Msg 4104, Level 16, State 1, Line 7
The multi-part identifier "ste.TransactionDate" could not be bound.
My current code is:
DATEDIFF(WEEKDAY, ste.TransactionDate, ste.SettlementDate) AS DaysToCSD,
and I did change this to
DECLARE #d1 datetime, #d2 datetime
SELECT #d1 = ste.TransactionDate, #d2 = ste.SettlementDate
SELECT DATEDIFF(dd, #d1, #d2) - (DATEDIFF(wk, #d1, #d2) * 2) -
CASE WHEN DATEPART(dw, #d1) = 1 THEN 1 ELSE 0 END +
CASE WHEN DATEPART(dw, #d2) = 1 THEN 1 ELSE 0 END
I am not great at SQL..not a dev...so any help appreciated!
I am getting error in below query.
Query
;with CTE as
(select Dm.Category_id as Category_Label_id,Ca.Category_Name as Category_label_Name,
convert(datetime, convert(varchar,year(getdate())) + '/' + convert(varchar,MONTH(GETDATE())) + '/' + convert(varchar, day(d.Expiry_Date))) as Exp_date1
,DATEDIFF(day,getdate(), convert(varchar(10), convert(varchar,year(getdate())) + '/' + convert(varchar,MONTH(GETDATE())) + '/' + convert(varchar, day(d.Expiry_Date)))) as Days_remain
,convert(datetime, DATEADD(day,-Reminder_Days, convert(varchar(10), convert(varchar,year(getdate())) + '/' + convert(varchar,MONTH(GETDATE())) + '/' + convert(varchar, day(d.Expiry_Date))))) as Exp_date2
from documentalert d
inner join document dm on dm.doc_id=d.doc_id
inner join Category ca on ca.Category_id = dm.Category_id
inner join category_value c on c.doc_id= dm.doc_id
inner join dbo.Category_Key k on k.Category_Key_id= c.category_label_id
and c.Category_Label_id=4 -- expiry date
where d.alerttype='M'
and dm.user_id=427 and dm.is_active=1 )
select * from cte where getdate() between Exp_date2 and Exp_date1
Error
Msg 242, Level 16, State 3, Line 1 The conversion of a varchar data
type to a datetime data type resulted in an out-of-range value.
I suspect that you are getting that error as you are building dates by taking the year and month from GETDATE() and then appending the day from Expiry_Date.
If any of your Expiry_Date values have the day as 31, then that will not work in the month of September, which GETDATE() will return:
Run the below:
SELECT CONVERT(DATETIME,
CONVERT(VARCHAR, YEAR(GETDATE())) + '/' +
CONVERT(VARCHAR, MONTH(GETDATE())) + '/' +
CONVERT(VARCHAR, 31) -- Fails with 31
) AS Exp_date1;
Errors with:
Msg 242, Level 16, State 3, Line 1
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
Where as this one works:
SELECT CONVERT(DATETIME,
CONVERT(VARCHAR, YEAR(GETDATE())) + '/' +
CONVERT(VARCHAR, MONTH(GETDATE())) + '/' +
CONVERT(VARCHAR, 30) -- Works with 30
) AS Exp_date1;
You need to either consider days and month values in your logic or use the Expiry_Date in a better way. I'm not sure why you want to append any day value to the current year and month. If you want to filter values to the current month, use a where clause to check the value first.
I was trying to concatenate the date and month with the Year and I need to check with the each record to find the financial year. When I execute the query it shows (The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.) error. Please help me to find the issue.
Code
set #SiteFileVal1='04-01'
set #SiteFileVal2='03-31'
set #SiteFileYear='2013'
SELECT bb.Amount
FROM Budget bb
JOIN Invoice i ON i.AccountId=bb.AccountId
WHERE bb.AccountId=i.AccountId
AND bb.Year=
(SELECT CASE WHEN (i.Date >= convert(datetime,#SiteFileVal1+'-'+convert(varchar(200),DATEPART(yyyy,i.Date)))
AND i.Date < convert(datetime,#SiteFileVal2+'-'+convert(varchar(200), DATEADD(yyyy,1,DATEPART(yyyy,i.Date))))) THEN year(#SiteFileYear) ELSE DATEADD(yyyy,-1,DATEPART(yyyy,i.Date)) END)
This part is incorrect:
DATEADD(yyyy,-1,DATEPART(yyyy,i.Date))
DATEADD expects a date passed in, and you are only passing in the year of a date -- DATEPART(yyyy, i.Date)
Using your code, I did:
select DATEADD(yyyy,-1,DATEPART(yyyy,'1/8/2007'));
The result? 1904-07-01 00:00:00.000
When I add a month/day back in, this is what I get:
select DATEADD(yyyy,-1, CAST(DATEPART(mm, '1/8/2007') as varchar) + '/' +
CAST(DATEPART(DD, '1/8/2007') as varchar) + '/' +
cast(DATEPART(yyyy,'1/8/2007') as varchar))
result: 2006-01-08 00:00:00.000
This is a lot of parsing for a query, but here's what you need, formatted to your column.
set #SiteFileVal1='04-01'
set #SiteFileVal2='03-31'
set #SiteFileYear='2013'
SELECT bb.Amount
FROM Budget bb
JOIN Invoice i ON i.AccountId=bb.AccountId
WHERE bb.AccountId=i.AccountId
AND bb.Year=
DatePart(yyyy,
(CASE WHEN (i.Date >= convert(datetime,#SiteFileVal1+'-'+convert(varchar(200),DATEPART(yyyy,i.Date)))
AND i.Date < convert(datetime,#SiteFileVal2+'-'+convert(varchar(200), DATEADD(yyyy,1,CAST(DATEPART(mm, i.Date) as varchar) + '/' +
CAST(DATEPART(DD, i.Date) as varchar) + '/' +
cast(DATEPART(yyyy,i.Date) as varchar)))))
THEN year(#SiteFileYear) ELSE
DATEADD(yyyy,-1, CAST(DATEPART(mm, i.Date) as varchar) + '/' +
CAST(DATEPART(DD, i.Date) as varchar) + '/' +
cast(DATEPART(yyyy,i.Date) as varchar)) END) )
Using SQL Server 2000
My Query.
SELECT
(Format(IIf(CLng(OutTime) > 180000, CDate('18:00:00'), CDate(Format(OutTime, '00:00:00'))) - IIf(CLng(InTime) < 90000, CDate('09:00:00'), CDate(Format(InTime, '00:00:00'))), 'hh:nn:ss')) As WorkTime,
(Format(IIf(CLng(InTime) < 90000, CDate('09:00:00') - CDate(Format(InTime, '00:00:00')), 0) + IIf(CLng(OutTime) > 180000, CDate(Format(OutTime, '00:00:00')) - CDate('18:00:00'), 0), 'hh:nn:ss')) As OverTime
FROM table
Above query is Access Query, I want to write a same query in sql.
Condition.
I want to Calculate the time after 090000(HH:MM:SS) before 180000 comes in worktime, before
090000 after 180000 comes in overtime.
Intime, Outime data type is varchar in the database
Am new to SQL Server 2000
How to write a SQL query from the above same?
Here is literally translated query to TSQL 2000.
Although, it could be rewritten for better performance:
Select Convert(char(8),
case when DateAdd(Day,-DateDiff(Day, 0, OutTime), OutTime)>'18:00:00'
Then Cast('18:00:00' as datetime)
Else DateAdd(Day,-DateDiff(Day, 0, OutTime), OutTime)
End
-
Case when DateAdd(Day,-DateDiff(Day, 0, InTime), InTime) <'09:00:00'
Then Cast('09:00:00' as datetime)
Else DateAdd(Day,-DateDiff(Day, 0, InTime), InTime)
End,
8
) as WorkTime,
Convert(char(8),
Case when DateAdd(Day,-DateDiff(Day, 0, InTime), InTime) <'09:00:00'
Then Cast('09:00:00' as datetime) -
DateAdd(Day,-DateDiff(Day, 0, InTime), InTime)
Else Cast('00:00:00' as datetime)
End
+
case when DateAdd(Day,-DateDiff(Day, 0, OutTime), OutTime)>'18:00:00'
Then DateAdd(Day,-DateDiff(Day, 0, OutTime), OutTime) -
Cast('18:00:00' as datetime)
Else Cast('00:00:00' as datetime)
End,
8
) as OverTime
From Table
Added later:
If InTime and OutTime have time part only (Date part is Jan 1 1900) you can use directly InTime and OutTime. Otherwise you have to extract time part from datetime column, as:
DateAdd(Day,-DateDiff(Day, 0, OutTime), OutTime)
(this is the fastest way to get time part only)
Instead of:
DateAdd(Day,-DateDiff(Day, 0, OutTime), OutTime)>'18:00:00'
You can use
Datepart(hh,OutTime)>17
P.S. as your time is stored as string yoiu don't need to get time part only. You can cast them to datetime, or you can write also
cast(left(inTime,2) as int) < 9
As a starter take a look at this website which shows you how to convert Access SQL statements into T-SQL as used by SQL server.
http://weblogs.sqlteam.com/jeffs/archive/2007/03/30/Quick-Access-JET-SQL-to-T-SQL-Cheatsheet.aspx
I don't think there's a very easy and simple way to do this - most notably because of storing time values in VARCHAR - this is really making this tricky.....
Anyway, I used an approach with two functions - one dbo.GetSeconds that converts a string representation of a time value ('103500' -> 10:35:00 hours) to a number of seconds, and then a second one dbo.GetOvertime that detects if there is any overtime.
CREATE FUNCTION dbo.GetSeconds(#input varchar(20))
RETURNS int
AS BEGIN
DECLARE #Hour INT
DECLARE #Minute INT
DECLARE #Second INT
DECLARE #TotalSeconds INT
SET #Hour = CAST(SUBSTRING(#input, 0, LEN(#input)-3) AS INT)
SET #Minute = CAST(LEFT(RIGHT(#input, 4), 2) AS INT)
SET #Second = CAST(RIGHT(#input, 2) AS INT)
SET #TotalSeconds = #Hour * 3600 + #Minute * 60 + #Second
RETURN #TotalSeconds
END
CREATE FUNCTION dbo.GetOvertime(#fromSeconds INT, #toSeconds INT)
RETURNS int
AS BEGIN
DECLARE #Overtime INT
SET #Overtime = 0
IF #fromSeconds < 32400 -- 32400 seconds = 09:00 hours
SET #Overtime = #OverTime + (32400 - #fromSeconds)
IF #toSeconds > 64800 -- 64800 seconds = 18:00 hours
SET #Overtime = #OverTime + (#toSeconds - 64800)
RETURN #Overtime
END
With those two functions in place, I can fairly easily calculate what you're looking for:
SELECT
dbo.GetOvertime(dbo.GetSeconds(InTime), dbo.GetSeconds(OutTime)) 'Overtime',
(dbo.GetSeconds(OutTime) - dbo.GetSeconds(InTime) -
dbo.GetOvertime(dbo.GetSeconds(InTime), dbo.GetSeconds(OutTime))) 'Worktime',
FROM YourTable
It's a bit involved - as I said, if you'd be on SQL Server 2008 and using the TIME data type, things would be a whole lot easier!
Marc
You could use substring and dateadd to convert the '090000' to a real datetime field. Then you can use CASE and DATEDIFF to split work and overtime. The final formatting can be done with CONVERT. Here's an example:
select
case when outtime-intime > '9:00:00' then '09:00:00'
else convert(varchar(30), outtime-intime, 108)
end as WorkTime,
case when outtime-intime <= '9:00:00' then '00:00:00'
else convert(varchar(30), outtime-intime-'9:00:00', 108)
end as OverTime
from (
select
dateadd(hh,cast(substring('090000',1,2) as int),0) +
dateadd(mi,cast(substring('090000',3,2) as int),0) +
dateadd(ss,cast(substring('090000',5,2) as int),0) as InTime,
dateadd(hh,cast(substring('180500',1,2) as int),0) +
dateadd(mi,cast(substring('180500',3,2) as int),0) +
dateadd(ss,cast(substring('180500',5,2) as int),0) as OutTime
) vw
This will print:
09:00:00 00:05:00
Here is code for SQL server 2000. 2005+ could do it without subquery using cross join.
Select DateAdd(mi, (Case When bef<0 Then bef else 0 end + Case When aft<0 Then aft else 0 end), diff) as WorkTome,
DateAdd(mi, (Case When bef>0 Then bef else 0 end + Case When aft>0 Then aft else 0 end), 0) as OverTime
From (
Select outTime-inTime as diff,
DateDiff(mi,t.inTime,'09:00') as bef,
DateDiff(mi,'18:00',t.outTime) as aft
From Table t ) as a
If Your inTime and outTime columns hase date part too, the query is slightly different:
Select DateAdd(mi, (Case When bef<0 Then bef else 0 end + Case When aft<0 Then aft else 0 end), diff) as WorkTome,
DateAdd(mi, (Case When bef>0 Then bef else 0 end + Case When aft>0 Then aft else 0 end), 0) as OverTime
From (
Select outTime-inTime as diff,
DateDiff(mi, DateAdd(Day,-DateDiff(Day, 0, t.inTime), t.inTime),'09:00') as bef,
DateDiff(mi,'18:00',DateAdd(Day,-DateDiff(Day, 0, t.OutTime), t.OutTime)) as aft
From #t t ) as a
I missed type of inTime and outTime.
Here is the version for varchar
Missed that, but you just have to do Cast(inTime as datetime) .
Use the first of previous 2 queries:
Select DateAdd(mi, (Case When bef<0 Then bef else 0 end + Case When aft<0 Then aft else 0 end), diff) as WorkTome,
DateAdd(mi, (Case When bef>0 Then bef else 0 end + Case When aft>0 Then aft else 0 end), 0) as OverTime
From (
Select Cast(t.outTime as datetime)-Cast(t.inTime as datetime) as diff,
DateDiff(mi,Cast(t.outTime as datetime),'09:00') as bef,
DateDiff(mi,'18:00',Cast(t.outTime as datetime)) as aft
From Table t ) as a