SQL create a list of dates based on current date - sql-server

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

Related

Script to filter by most recent end of week date

My company's reporting week is Monday through Sunday. On Monday morning's I run several queries using Microsoft SQL Server Management Studio to report on business activity for the previous week. I currently use declaration statements to pull the desired date range. This works quite well as long as I'm running reports on Monday. However, if Monday was a holiday and I'm not running reports until Tuesday, I need to manually modify my date range for each query. How can I modify my date filter to retrieve records through the previous "Sunday" so it doesn't matter what day I actually run the report.
Here's a sample query;
Declare #DATEFROM SMALLDATETIME = (CONVERT(datetime, getdate() + cast('00:00' as datetime)) - 8), #DATETO smalldatetime = (CONVERT(datetime, getdate() + cast('23:59' as datetime))-2);
Create Table #SALES ([PartNumber] CHAR(5), [DateSold] SMALLDATETIME)
Insert Into #SALES Select '10190', '6/3/2018 11:00'
Insert Into #SALES Select '10213', '6/8/2018 8:00:00 AM'
Insert Into #SALES Select '10214', '6/5/2018 9:30:00 AM'
Insert Into #SALES Select '10215', '6/4/2018 1:00:00 PM'
Insert Into #SALES Select '10217', '6/6/2018 1:00:00 PM'
Insert Into #SALES Select '10219', '6/7/2018 12:00:00 PM'
Insert Into #SALES Select '10220', '6/9/2018 3:30:00 PM'
Insert Into #SALES Select '10221', '6/11/2018 8:30:00 AM'
Insert Into #SALES Select '10222', '6/11/2018 2:30:00 PM'
Insert Into #SALES Select '10225', '6/8/2018 8:00:00 AM'
Insert Into #SALES Select '10227', '6/10/2018 9:00:00 AM'
Insert Into #SALES Select '10231', '6/10/2018 1:00:00 PM'
Insert Into #SALES Select '10233', '6/2/2018 8:00:00 AM';
SELECT S.PartNumber, S.DateSold
FROM #SALES S
WHERE DATESOLD BETWEEN #DATEFROM AND #DATETO
ORDER BY DateSold;
DROP TABLE #SALES
First, a few items of interest:
SQL Server's SET DATEFIRST command allows you to choose any weekday as the first day of the week, from 1 (Monday) through 7 (Sunday).
You can query the current value of this setting using the expression ##datefirst.
DATEPART(weekday, getdate()) will return a number for the current weekday where 1 indicates the day set by SET DATEFIRST, 2 indicates the day after, etc.
So suppose I want to answer the question: how many days prior to some arbitrary date #TestDate was the most recent Monday? The number of days that have passed since the most recent beginning of a week is DATEPART(weekday, #TestDate) - 1, and the number of days that pass between a Monday and the beginning of a week is ##datefirst - 1, so the number of days that have passed since the most recent Monday is the sum of those quantities modulo 7:
declare #TestDate date = convert(date, getdate());
declare #DaysPastMonday int = (##datefirst + datepart(weekday, #TestDate) - 2) % 7;
With this information you can get your date range very easily:
declare #DateTo date = dateadd(day, -#DaysPastMonday, #TestDate);
declare #DateFrom date = dateadd(day, -7, #DateTo);
But note that both of the dates I've selected here are Mondays, whereas you want a Monday through a Sunday. The reason I've done it this way is that if you're going to be looking at fields that potentially have a time component as well as a date (e.g., datetime or datetime2), and you want to use BETWEEN, then you need to make sure that your end date has the latest time of day that SQL Server is capable of representing. I find it cleaner to use a date range that's inclusive on the start date and exclusive on the end date. So in place of an expression like this:
x BETWEEN #DateFrom AND #DateTo
You'd write your queries to use an expression like this:
x >= #DateFrom AND x < #DateTo
Declare #DATEFROM datetime = DATEADD(wk, DATEDIFF(wk, 6, GETDATE()), 0),
#DATETO datetime = DATEADD(ms, -3, (select DATEADD(wk, DATEDIFF(wk, 6, GETDATE()), 7)));

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 Server - Date String

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)

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'

SQL Server query to calculate total for number of weeks in a given month name

I need to create a report where I will just pass month (February) and year (2011) and want the sum(total) but output desired like this... I don't know how to calculate total weekwise
Week-1......Week-2......Week-3......Week-4....Total
---------------------------------------------------
Working example
Sample table, contains just 2 columns thedate datetime, amount numeric
select cast(datediff(d, number%1000, getdate()) as datetime) as thedate, number as amount
into testtable
from master..spt_values
The query taking month and year as params
declare #month int, #year int
select #month = 2, #year = 2011
select *
from
(
select
amount,
'Week-' + right(dense_rank() over (order by datepart(wk, thedate)),1) week_in_month
from testtable
where thedate >= cast(#year*10000+#month*100+1 as char(8))
and thedate < dateadd(m,1,cast(#year*10000+#month*100+1 as char(8)))
) P
pivot (sum(amount) for week_in_month in ([Week-1],[Week-2],[Week-3],[Week-4],[Week-5])) V
Note:
cast(#year*10000+#month*100+1 as char(8)) : first day of month
dateadd(m,1,..) : first day month after

Resources