SQL Server - Date String - sql-server

Can you please help me create an sql statement that will get the previous date and concatenate that date in this format:
'2016-05-05 00:00:00'
I already know the sql function to get the previous date but I don't know yet on how to get the time in the expected format. My query is something like this
Select *
from table
where
transaction_date between '2016-05-05 00:00:00' and '2016-05-05 23:59:59'
So I need 00:00:00 and 23:59:59 to be concatenated in the date.

You don't need the times at all. Just don't use BETWEEN and use >= and < for the next day, like this:
SELECT *
FROM table
WHERE transaction_date >= '2016-05-05'
AND transaction_date < '2016-05-06'
Or if you only have the single date value:
DECLARE #date DATETIME = '2016-05-05'
SELECT *
FROM table
WHERE transaction_date >= #date
AND transaction_date < DATEADD(DAY, 1, #date)
The added benefit of doing it this way is that you also don't miss out on times that occur in the last second of the day as your original query does. For example 2016-05-05 23:59:59.001
Edit: From the comments below
To get yesterdays date, get today's date and subtract a day from it:
DECLARE #date DATETIME = DATEADD(DAY, -1, CAST(GETDATE() AS DATE))
Now use the logic as mentioned above.

This function:
DATEADD(dd, DATEDIFF(dd, 0, GetDate()), 0)
...will turn 2016-05-05 18:18:231 into 2016-05-05 00:00:000. From there it is easy to get full date boundaries by adding and subtracting days:
DECLARE #Date DATETIME
,#YesterdayStartDate DATETIME
,#TodayStartDate DATETIME
SET #Date = GetDate()
SET #TodayStartDate = DATEADD(dd, DATEDIFF(dd, 0, #date), 0)
SET #YesterdayStartDate = DATEADD(dd, -1, #TodayStartDate)
SELECT #Date, #YesterdayStartDate, #TodayStartDate
SELECT *
FROM Table
WHERE
transaction_date >= #YesterdayStartDate AND
transaction_date < #TodayStartDate

This will give you the result with transaction_date on yesterday.
SELECT
*
FROM
TABLE
WHERE
transaction_date BETWEEN dateadd(DAY, datediff(DAY, 1, GETDATE()), 0) AND dateadd(DAY, 1, dateadd(DAY, datediff(DAY, 1, GETDATE()), 0))

Compare date with out time part . ie below code.
Select * from table
where CONVERT(VARCHAR(8), transaction_date , 112) = CONVERT(VARCHAR(8), getdate(), 112)

Related

How to get date from day name?

How can I get the date of specific day ? Like if I have Thursday or month number ?
If I give 12 for instance I want to get the date of 12th day of this month. Or if I give 'Sun' or 'Sat' is it possible to get the dates of these days ?
DATEFROMPARTS function can construct a date from day, month and year.
DATEPARTS does the opposite - gives you the day, month, year, hour, etc. of a date. Or you can use functions like YEAR, MONTH and DAY.
You can deconstruct the value returned by GETDATE function and construct whatever date you want. Here is for example how to get the date for 12th day of the current month:
select DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 12)
Converting 'Sun' or 'Sat' to date is a bit more difficult. First, they aren't quite deterministic. If today is Friday, "Sunday this week" means "next Sunday" in some parts of the world and "last Sunday" in others. You should implement your own logic based on the value returned by DATEPART(dw, GETDATE()) (which will give you the day of the week).
To find the weekday of the current month
DECLARE #daynumber INT = 12
SELECT datename(weekday, dateadd(d, #daynumber - 1, getdate()))
To find the dates of the current month of a given weekday
DECLARE #dayname char(3) = 'sat'
;WITH CTE as
(
SELECt TOP
(datediff(D, eomonth(getdate(), -1),eomonth(getdate())))
dateadd(d,row_number()over(ORDER BY 1/0),
eomonth(getdate(),-1))date
FROM
(values(1),(2),(3),(4),(5),(6))x(x),
(values(1),(2),(3),(4),(5),(6))y(x)
)
SELECT day(date) monthday, date
FROM CTE
WHERE left(datename(weekday, date),3) = #dayname
select sysdatetime(); --2018-12-13 16:29:56.0560574
---If I give 12 for instance I want to get the date of 12th day of this month.
declare #numDate int = 12;
select dateadd(m, datediff(m,0,getdate()),#numDate - 1 ); --2018-12-12 00:00:00.000
--Or if I give 'Sun' or 'Sat' is it possible to get the dates of these days ?
declare #text nvarchar(20) = 'Sunday';
declare #dateStart date = dateadd(month, datediff(month, 0, sysdatetime()), 0),
#days int =( select (DAY(dateadd(dd,-1,DATEADD(m,1,cast(2018 as varchar(4)) + '-' + cast(12 as varchar(2)) +'-01')))));
declare #dateEnd date = DATEADD(day,#days-1,#dateStart);
;WITH CTE (Dates,EndDate) AS
(
SELECT #dateStart AS Dates,#dateEnd AS EndDate
UNION ALL
SELECT DATEADD(day,1,Dates),EndDate
FROM CTE
WHERE DATEADD(day,1,Dates) <= EndDate
)
SELECT CTE.Dates, DATENAME(DW, CTE.Dates)
FROM CTE
where DATENAME(DW, CTE.Dates) = #text;
Result:
Dates,Day
2018/12/2,Sunday
2018/12/9,Sunday
2018/12/16,Sunday
2018/12/23,Sunday
2018/12/30,Sunday
-- Here is how to get week day name to week day number
DECLARE #T TABLE (Dow INT, NameOfDay VARCHAR(15), ShortName CHAR(3));
WITH Days AS
(
SELECT TOP 7
ROW_NUMBER() OVER(PARTITION BY object_id ORDER BY object_id) AS RowNo
FROM
sys.all_columns
)
INSERT INTO #T
SELECT
RowNo,
DATENAME(WEEKDAY, RowNo - 1),
LEFT(DATENAME(WEEKDAY, RowNo - 1), 3)
FROM
Days
SELECT
*
FROM
#T;
-- Here is how to get start of period
SELECT
DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0) AS StartOfDay,
DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()), 0) AS StartOfWeek,
DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0) AS StartOfMonth,
DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0) AS StartOfYear;
-- An example
WITH
StartPeriods AS
(
SELECT DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()), 0) AS StartOfWeek
),
SelectedDay AS
(
SELECT
Dow - 1 AS Dow,
(SELECT StartOfWeek FROM StartPeriods) AS StartOfWeek
FROM
#T
WHERE
ShortName = 'Wed'
)
SELECT
DATEADD(DAY, Dow, StartOfWeek)
FROM
SelectedDay;

SQL Date Col - Use DATE or Varchar?

I have very simple code, but the issue is that when I convert a date column to Varchar(10), then I am not fetching distinct dates and sort is not working as desired; when I use DATE format, then I am fetching distinct dates and date sort is working, but I get datetime - 2017-02-01 12:00:00 AM (I don't want the time part)
Here is the code:
SELECT DISTINCT
--CONVERT(varchar(10), DATEADD(month, DATEDIFF(month, 0, (MyDate)), 0), 101) AS MonthValue,
CONVERT(DATE, DATEADD(month, DATEDIFF(month, 0, (MyDate)), 0)) AS MonthValue
FROM dbo.Mytable
WHERE MyDate >= GETDATE()-366
ORDER BY MonthValue DESC

SQL create a list of dates based on current date

I have a column of dates that range from 2015-06 to 2013-04. The date range will grow as I put in more data. How do I write a query where the date is always a X amount of months before the current date?
date
2015-06
2015-05
2015-04
2015-03
2015-02
for example I want it to be:
Select *
From dbo.name
Where date in (X months ago from current date)
if todays date is 2015-12 and I want 3 months ago, I want the query to be:
Select *
From dbo.name
Where date in ('2015-11','2015-10','2015-09')
Thanks
Select *
From dbo.name
Where CAST([Date] + '-01' AS DATE) >= DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) -3, 0)
Since your date strings are in yyyy-mm format you can do string comparison using < > =. You just need to convert the current date to varchar(7) using style 126 (yyyy-mm-ddThh:mi:ss.mmm)
For Example
DECLARE #CurrentDate DATETIME = GETDATE()
DECLARE #XMonthsAgo INT = 3
DECLARE #Dates TABLE ([date] varchar(7))
INSERT INTO #Dates VALUES
('2015-09'),('2015-08'),('2015-07'),('2015-06'),('2015-05'),('2015-04'),('2015-03'),
('2015-02'),('2015-01'),('2014-12'),('2014-11'),('2014-10'),('2014-09'),('2014-08'),
('2014-07'),('2014-06'),('2014-05'),('2014-04'),('2014-03'),('2014-02'),('2014-01')
SELECT *
FROM #Dates d
WHERE [date] >= CONVERT(VARCHAR(7), DATEADD(month, -#XMonthsAgo, #CurrentDate), 126)
AND [date] < CONVERT(VARCHAR(7), #CurrentDate, 126)
Result
date
----
2015-07
2015-06
2015-05

Displaying dates values for current date in SQL Server

I am trying to filter out the values based on the date which should be within today's date. I am using the below query, however the query is not working as expected.
This is what I am using in SQL Server.
select values
from table
where date between DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)
and GETDATE()
I am expecting the date to be filtered for values between '2015-03-18 00:00:00' AND '2015-03-18 23:59:59' if I am executing the query on 18th March 2015.
Please guide.
It's much better to use a >= and < than BETWEEN:
SELECT *
FROM Table
WHERE
date >= CAST(CAST(GETDATE() AS DATE) AS DATETIME)
AND date < DATEADD(DAY, 1, CAST(CAST(GETDATE() AS DATE) AS DATETIME))
CAST(CAST(GETDATE() AS DATE) AS DATETIME) will get you the current date without the time part that is 2015-03-18 00:00:00
DATEADD(DAY, 1, CAST(CAST(GETDATE() AS DATE) AS DATETIME)) will get you the next day, again without the time part.
So in turn, your WHERE condition would be:
WHERE
date >= '2015-03-18 00:00:00'
AND date < '2015-03-19 00:00:00'
Alternatively, you can use this:
SELECT *
FROM Table
WHERE
date >= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0) -- beginning of this day
AND date < DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) + 1, 0) -- beginning of next day
For more date calculations, refer to this article.
As You are Expecting value between '2015-03-18 00:00:00' AND
'2015-03-18 23:59:59. so, you can simply compare only date part.
you can Use Cast()/Convert():
SELECT *
FROM Table
WHERE
cast(date as date) =cast(getdate() as date)
It included 2015-03-18 00:00:00' AND '2015-03-18 23:59:59'

To calculate average of date differences in a column in sql server

I need to calculate average of date differences excluding weekends across rows in a column. The query gives me wrong results. But, when i calculate it myself, i get different results. the query is something like -
select zone, avg(datediff(dd,startdate,enddate)-datediff((ww,startdate,enddate)*2)) from table where startdate >'1/1/2013' group by zone
I don't get correct results. Please guide me.
try this code:
select zone , avg(NumOfDays) from
(select zone, (datediff(dd,startdate,enddate)-datediff((ww,startdate,enddate)*2)) as NumOfDays from table where startdate >'1/1/2013')
group by zone
I don't know how your data looks like and what you challenge exactly is but I think your problem is "excluding weekend"? Maybe this helps you?
First create a function that counts every weekend day between your period for filtering it later:
CREATE FUNCTION fnc_GetWeekendDays(#dFrom DATETIME, #dTo DATETIME)
RETURNS INT AS
BEGIN
Declare #weekendDays int
Set #weekendDays = 0
While #dFrom <= #dTo
Begin
If ((datepart(dw, #dFrom) = 1) OR (datepart(dw, #dFrom) = 7))
Set #weekendDays = #weekendDays + 1
Set #dFrom = DateAdd(d, 1, #dFrom)
End
Return (#weekendDays)
END
After this, write your query:
Select
zone,
avg(cast((datediff(SECOND,StartTime,EndTime) - dbo.fnc_GetWeekendDays(StartTime, EndTime)*86400) as float))
from
(
Select zone,
CASE
WHEN (datepart(dw, startdate) = 1) THEN DATEADD(Day, DATEDIFF(Day, 0, startdate), 1)
WHEN (datepart(dw, startdate) = 7) THEN DATEADD(Day, DATEDIFF(Day, 0, startdate), 2)
ELSE startdate END as StartTime,
CASE
WHEN (datepart(dw, enddate) = 1) THEN DATEADD(Day, DATEDIFF(Day, 0, enddate), -2)
WHEN (datepart(dw, enddate) = 7) THEN DATEADD(Day, DATEDIFF(Day, 0, enddate), -1)
ELSE enddateEND as EndTime
from table
) subquery
where StartTime < EndTime and startdate >'2013-01-01 00:00:00.000'
Group by zone
You will get your average time in seconds, if you want another format you have to calculate it...

Resources