Why Week conversion failed in SQL Server in my case? - sql

I am trying to convert week of the date based on my criteria.
My date condition: if my #date is less than 4 AM, then #date - 1, else #date
declare #dates datetime
set #dates = '2019-01-01 03:59:59'
select
case
when convert(varchar(26), #dates, 108) <= '04:00:00'
then convert(varchar, dateadd(day, -1, #dates), 103)
else convert(varchar, #dates, 103)
end BusinessDate
Output:
31/12/2018 // as expected
Now I want to find the week number of the output. So I tried
declare #dates datetime
set #dates = '2019-01-01 03:59:59'
select
case
when convert(varchar(26), #dates, 108) <= '04:00:00'
then convert(varchar, dateadd(day, -1, #dates), 103)
else convert(varchar, #dates, 103)
end BusinessDate,
case
when convert(varchar(26), #dates, 108) <= '04:00:00'
then datepart(week, convert(datetime, convert(varchar, dateadd(day, -1, #dates), 103)))
else datepart(week, convert(datetime, convert(varchar, #dates, 103)))
end weeks
But I get this error:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.

Just subtract four hours:
select datepart(week,
dateadd(hour, -4, #dates)
)

Related

Problem in Convert mm/dd/yyyy To dd/mm/yyyy

I need to have same result for these two queries with format: 'dd/mm/yyyy
what should I do?
DECLARE #Date varchar(10) = '01/02/1958'
SELECT
CASE
WHEN TRY_CONVERT(Date, #Date, 103) IS NOT NULL
THEN CONVERT(Date, #Date, 103)
ELSE TRY_CONVERT(Date, #Date)
END
DECLARE #Date2 Date = '01/02/1958'
SELECT
CASE
WHEN TRY_CONVERT(Date, #Date2, 103) IS NOT NULL
THEN CONVERT(Date, #Date2, 103)
ELSE TRY_CONVERT(Date, #Date2)
END
Since you are using 2 types of date in your strings, when you write DECLARE #Date2 Date = '01/02/1958', you are saying 'I whant to convert that string in a date based on my server configuration'.
With that :
DECLARE #Date varchar(10) = '01/02/1958'
SELECT
CASE
WHEN TRY_CONVERT(Date, #Date, 103) IS NOT NULL
THEN CONVERT(Date, #Date, 103)
ELSE TRY_CONVERT(Date, #Date)
END
DECLARE #Date2 Date = '01/02/1958'
SET #Date2 = CONVERT(Date,(CONVERT(VARCHAR,#Date2,101)),103);
SELECT
CASE
WHEN TRY_CONVERT(Date, #Date2, 103) IS NOT NULL
THEN CONVERT(Date, #Date2, 103)
ELSE TRY_CONVERT(Date, #Date2)
END
I'm saying 'Ok, convert the #Date2 from US to EU convention. When manipulating Date formats, be sure to always cast your string with a correct format

DateDiff In months between two different types date formats

I have two date formats, EndDate in YYYYMMDD format and another Monthfirstdate in YYYY-MM-DD FORMAT. I need to get the difference between these two dates.
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE #Date DATE = dbo.value('DATE')
SELECT
E.EmployeeID
,E.StartDateKey
,E.EndDateKey
,E.FromDateKey
,E.ToDateKey
INTO #Employee
FROM
dbo.Employee E
---clean--
DECLARE #StartDate DATE = (SELECT DATEADD(YY, DATEDIFF(YY, 0, #Date) - 1, 0))
DECLARE #EndDate DATE = DATEADD(S, -1, DATEADD(MM, DATEDIFF(MM, 0, #Date) + 3, 0))
SELECT
E.EmployeeID
,CAST(CONVERT(VARCHAR(10), E.StartDateKey, 112) AS INT) AS _EmployeeStartDateKey
,CAST(CONVERT(VARCHAR(10), E.EndDateKey, 112) AS INT) AS _EmployeeFinishDateKey
,CAST(CONVERT(VARCHAR, D.MonthFirstDay, 112) AS INT) AS _DateKey
,???? AS [Tenure]
FROM #Employee AS E
INNER JOIN dbo.Date D ON
D.DateKey BETWEEN E.FromDateKey AND E.ToDateKey
WHERE
D.DateKey BETWEEN #tartDate AND #EndDate
AND D.DayOfMonth = 1
You can try below query in SQL Server:
DECLARE
#firstDate DATETIME = '2022-12-01',
#dateinStringFormat VARCHAR(20)= '20121201',
#endDate DATETIME;
--Converting date string to Datetime format(YYYY-MM-DD)
SELECT #endDate = CONVERT(CHAR(10), CONVERT(datetime, #dateinStringFormat), 120);
--Now, Calculating the date difference in Month
SELECT DATEDIFF(MONTH, #endDate, #firstDate) AS DateDiff;

Monthly wise count using date calculation

I have the table named company with columns company name, create date, etc.
I want to get the count of companies created for this month.
I have the stored procedure for weekly wise count
CREATE PROCEDURE [dbo].[pr_NewCmpCount]
#StartDate DATETIME = NULL --'20130508'
, #EndDate DATETIME = NULL --'20130515'
AS
BEGIN
DECLARE #DateDiff INT
, #MainDate DATETIME
IF #StartDate IS NULL AND #EndDate IS NULL
BEGIN
IF (DATEPART(dw,GETDATE()) > 3)
SET #DateDiff = 0
ELSE
SET #DateDiff = 6
SET #MainDate = DATEADD (MINUTE, -30, DATEADD (HOUR, -5, DATEADD(wk, DATEDIFF(wk,#DateDiff,GETDATE()), 0)))
SELECT #StartDate = DATEADD (MINUTE, -30, DATEADD (HOUR, -5, DATEADD(wk, DATEDIFF(wk,0,#MainDate), -5)))
SELECT #EndDate = DATEADD (MINUTE, -30, DATEADD (HOUR, -5, DATEADD(wk, DATEDIFF(wk,0,#MainDate), 2)))
SELECT CONVERT (VARCHAR, Count(*)) AS [Count]
, CONVERT (DATE, DATEADD (DD, 1, #StartDate)) AS [StartDate]
, CONVERT (DATE, #EndDate) AS [EndDate]
FROM
Company WITH(NOLOCK)
WHERE CreateDate >= #StartDate
AND CreateDate < #EndDate
END
ELSE
IF ((CONVERT (DATE, #StartDate) < CONVERT (DATE, #EndDate)) AND (CONVERT (DATE, #EndDate) < CONVERT (DATE, GETDATE())))
BEGIN
SET #StartDate = CONVERT (DATE, #StartDate)
SET #EndDate = CONVERT (DATE, #EndDate)
SELECT #StartDate = DATEADD (MINUTE, -30, DATEADD (HOUR, -5, #StartDate))
SELECT #EndDate = DATEADD (MINUTE, 30, DATEADD (HOUR, 18, #EndDate))
SELECT CONVERT (VARCHAR, Count(*)) AS [Count]
, CONVERT (DATE, DATEADD (DD, 1, #StartDate)) AS [StartDate]
, CONVERT (DATE, #EndDate) AS [EndDate]
FROM
Company WITH(NOLOCK)
WHERE CreateDate >= #StartDate
AND CreateDate < #EndDate
END
ELSE
SELECT 'Please Run After Tuesday of Every Week or Given the Valid Date' [Count]
, CONVERT (DATE, #StartDate) AS [StartDate]
, CONVERT (DATE, #EndDate) AS [EndDate]
END
Output for this stored procedure is
Count Startdate EndDate
10 2016-03-13 2016-03-22
Expected output
Count Startdate EndDate
20 2016-02-01 2016-02-29
Where do I need to modify in my stored procedure to get monthly wise count?
Something like this:
DECLARE #StartDt Date
DECLARE #EndDt date
SELECT #StartDt,#EndDt,Count(*) AS TotalCompanies FROM company
WHERE [create date] BETWEEN #StartDt AND #EndDt
I skipped the stored procedure formatting for simplicity.

TSQL Date conditions

I have a table of events, constantly being updated, with a datetime column.
I want to get all events that start today as well as the ones that start 8 hours into the next day.
The idea is that people don't really check in the middle of the night for events, so we list them in the day before.
To get today's I do DATEDIFF(day,eventdate,GETDATE())=0 but I havn't figured out how to do the dateadd() for my case. I either get no rows or too many.
So the wanted result is:
From 00:00 on March 9 to 8:00 on March 10. (example only)
It is better to not do any calculation on your column. Calculate the interval instead and fetch the rows that is in the interval. That way you can make use of a index on eventdate instead of doing a table scan.
select SomeColumns
from YourTable
where eventdate >= dateadd(day, datediff(day, 0, getdate()), 0) and
eventdate < dateadd(hour, 32, dateadd(day, datediff(day, 0, getdate()), 0))
You can use these to bound your query...
DECLARE #Start DateTime = CONVERT(nvarchar(10), GetDate(), 121)
DECLARE #End DateTime = DATEADD(Hour, +32, #Start)
Here's a Test Script
CREATE TABLE #Temp (Column1 DateTime)
INSERT INTO #Temp (column1) values (getdate()) -- it's 6pm now
INSERT INTO #Temp (column1) values (dateadd(hour, -24, getdate())) --6pm yesterday - outside window
INSERT INTO #Temp (column1) values (dateadd(hour, -12, getdate())) --6am today
INSERT INTO #Temp (column1) values (dateadd(hour, -5, getdate())) -- 1pm today
INSERT INTO #Temp (column1) values (dateadd(hour, +12, getdate())) -- 6am tomorrow - inside window
INSERT INTO #Temp (column1) values (dateadd(hour, +17, getdate())) -- 11am tomorrow - outside window
select * from #Temp
DECLARE #Start DateTime = CONVERT(nvarchar(10), GetDate(), 121)
DECLARE #End DateTime = DateAdd(Hour, +32, #Start)
SELECT * FROM #Temp WHERE Column1 > #Start AND Column1 < #End
SELECT
Column1, Column2
FROM
TableName
WHERE
DateColumm BETWEEN Convert(Date, GETDATE()) AND DateAdd(hh, 32, Convert(smalldatetime, Convert(Date, GETDATE())))
You can also do it this way:
select *
from yourtable
WHERE EventDate >= Convert(varchar(10), getdate(), 101)
AND EventDate < CAST(Convert(varchar(10), DateAdd(d, 1, getdate()), 101) + ' 08:00 AM' as datetime)
Then if you EventDate has the time on it, then you can convert the EventDate in the first part of your WHERE clause
select *
from yourtable
WHERE Convert(varchar(10), EventDate, 101) >= Convert(varchar(10), getdate(), 101)
AND EventDate < CAST(Convert(varchar(10), DateAdd(d, 1, getdate()), 101) + ' 08:00 AM' as datetime)
You can try something like this.
The DateAdd documention page shows all the different date parts you can use (hour, day, seconds, etc.)
DECLARE #StartTimeWindow DATETIME, #EndTimeWindow DATETIME
SET #StartTimeWindow = DATEDIFF(DAY, 0, GETDATE())
SET #EndTimeWindow = DATEADD(HOUR, 32, #StartTimeWindow)
SELECT *
FROM EventTable
WHERE EventDate >= #StartTimeWindow
AND EventDate <= #EndTimeWindow

How do I compare against the current week using SQL Server?

How do I compare an SQL Server date column against the current week?
For instance:
WHERE [Order].SubmittedDate = *THIS WEEK*
You could convert your date to a week number and compare this to the week number from the current date. Likewise, you'll need to compare the year as well, so that you don't get last year's weeks.
WHERE DATEPART(wk, [Order].SubmittedDate) = DATEPART(wk, GETDATE())
AND DATEPART(yy, [Order].SubmittedDate) = DATEPART(yy, GETDATE())
Assuming you are meaning always "this week" and there are no records with Submitted dates in the future, which I imagine could be the case you can do:
WHERE [Order].SubmittedDate >= DATEADD(dd, -(DATEPART(dw, GETDATE()) -1), GETDATE())
If dates do go into the future, the full restriction to this week is:
WHERE [Order].SubmittedDate >= DATEADD(dd, -(DATEPART(dw, GETDATE()) -1), GETDATE())
AND [Order].SubmittedDate < CAST(CONVERT(VARCHAR(10), DATEADD(dd, (8 - DATEPART(dw, GETDATE())), GETDATE()), 120) AS DATETIME)
I'd strongly recommend using a clause based on a start and end date like this, as it will allow efficient index use so should perform better.
Try this:
WHERE [Order].SubmittedDate BETWEEN
DATEADD(d, - DATEPART(dw, GETDATE()) + 1, GETDATE()) AND
DATEADD(d, 7 - DATEPART(dw, GETDATE()) , GETDATE())
Maybe this can run faster, as doesn't needs to be evaluated everytime:
DECLARE #StartDate DATETIME,
#EndDate DATETIME
SELECT #StartDate = DATEADD(d, - DATEPART(dw, GETDATE()) + 1, GETDATE()),
#EndDate = DATEADD(d, 8 - DATEPART(dw, GETDATE()) , GETDATE())
-- // Strip time part, so week starts on Sunday 00:00
SELECT #StartDate = CAST(FLOOR(CAST(#StartDate AS FLOAT)) AS DATETIME),
#EndDate = CAST(FLOOR(CAST(#EndDate AS FLOAT)) AS DATETIME)
...
WHERE [Order].SubmittedDate >= #StartDate AND [Order].SubmittedDate < #EndDate