Data Preparation End OF Every Month - Moving Over 12 Months - sql

I have data prep procedure in SQL. I want to have data preparation at the end of every month
Say I want the procedure run on last day of month e.g. on 31 January 2020 it should prep data from 1 January to 31 January.
So it's kind of moving window over all months of the year. Because I need data for evaluation at the end of each month.
I tried this, however, this does not give automation. Its sort of manual running end of every month
select '2020-10-01' as beginDate_AnalysisWindow
, '2020 -01-31' as endDate_AnalysisWindow
into #AnalysisWindow --create temporary table #AnalysisWindow
I also tried the following, however, I’m not sure if it does for the whole month or just one day?
SELECT START_OF_MONTH_DATE AS beginDate_AnalysisWindow
,END_OF_MONTH_DATE AS endDate_AnalysisWindow
INTO #AnalysisWindow
FROM [dbo].[Date] WITH (NOLOCK)
WHERE DATE = DATEADD(dd, - 1, CAST(GETDATE() AS DATE))
Could someone pls help me/give me some suggestions.
Thanks in advance

If you want the last day of the current month, use eomonth():
WHERE DATE = CONVERT(date, EOMONTH(GETDATE()))
Note: This assumes that the date column has no time component. If that is the case:
WHERE CONVERT(date, DATE) = CONVERT(date, EOMONTH(GETDATE()))
SQL Server will still use an index (if available) even for this type of conversion.
EDIT:
To get the current months data, one method is:
WHERE DATE <= CONVERT(date, EOMONTH(GETDATE())) AND
DATE > CONVERT(date, EOMONTH(GETDATE(), -1))
The second argument to EOMONTH() is a months offset.

You can also try:
where getdate() <= EOMONTH(GETDATE()) AND
getdate() > DATEADD(DAY, 1, EOMONTH(GETDATE(), -1))
Instead of getdate(), you can use your date column.

Related

Needing to get first of month in SQL Server, but from yesterday's date

I am working on a report that will send daily with the full months data minus the current day as it sends early and won't have relevant data from today.
Currently the parameter for the start as =dateadd(“m”,1,dateserial(year(Today),month(Today),0))
and the end as =DateAdd("d",-1,Today())
The problem is that this will skip the last day of each month. I want to change the start date to the first of the month from today - 1 day, but I am not sure how to do this?
I could change it to send with the current days data as well but with it sending at 8 AM the data would still be missing.
Probably least amount of code is to (1) subtract a day from today, (2) take the eomonth of the previous month, and (3) add a day.
SELECT DATEADD(DAY, 1, EOMONTH(DATEADD(DAY, -1, GETDATE()),-1));
I'm not sure what language you're doing dateserial stuff in but I'd personally do this inside SQL Server.
Also the best way to drive a report for any period is to say:
col >= start of the period
AND
col < start of *next* period
For example, for a report to cover all of last month (I realize that's not quite what you're doing, it's just a simpler example), I would say:
DECLARE #start date = DATEADD(DAY, 1, EOMONTH(GETDATE(), -2));
...
WHERE date_column >= #start
AND date_column < DATEADD(MONTH, 1, #start);
This way you don't get bitten by all of the problems that can happen with various date/time types as you try to figure out what is the end of a day or month.
For month-to-date covering yesterday and not today, I would say:
DECLARE #today date = GETDATE();
DECLARE #start date = DATEADD(DAY, 1, EOMONTH(DATEADD(DAY, -1, #today),-1));
... WHERE date_column >= #start
AND date_column < #today;

SQL SELECT SUM BETWEEN 1 Year from now to start ot the year

so I'm kinda stuck with a little query to get the SUM of the time period I want. So it already works but I want that it's automatically between 1 year from now and the beginning of the year.
SELECT SUM(N_EXCL), S_CUSTNO, S_CUSTNAME1, D_INVOICEDATE
from sao.INVOICE_P i
WHERE D_INVOICEDATE > DATEADD (year, -1, getdate ())
AND D_INVOICEDATE < DATEADD (month , -6 ,Getdate () )
GROUP BY S_CUSTNO, S_CUSTNAME1, D_INVOICEDATE
Currently I would have to change the query every month but I try to find a way to avoid it.
Ok. Maybe i wasn't clear enough. My problem is the -6 i have to write down. I want to switch it to a parameter that will automatically change up the date so that i get data from 01.01.2021 - 22.06.2021. So same date, but different year.
If I understand your question, you should be able to do this:
SELECT SUM(N_EXCL), S_CUSTNO, S_CUSTNAME1, D_INVOICEDATE
from sao.INVOICE_P i
WHERE D_INVOICEDATE between DATEADD(year, -1, getdate()) AND DATEFROMPARTS(getdate(), 1, 1)
GROUP BY S_CUSTNO, S_CUSTNAME1, D_INVOICEDATE
So instead of using where and I'm using where between. And I'm checking for todays date last year till 1st of January current year.
If you need from 1st of January previous year you can use:
between DATEFROMPARTS(year(getdate() -1), 1, 1) AND DATEADD(year, -1, getdate())

Pull data from the third week back from this week? [duplicate]

This question already has answers here:
Query to get content older than 3 weeks
(3 answers)
Closed 2 years ago.
This week is the week of 12/28/20. I want to pull data from the third week back of whatever the current week is. So if I run my query today I want it to pull data for the week of 12/7 only. I'm trying to do this and its not returning any results. Any ideas? Thank you
WHERE date = DATEADD(week, -3, GETDATE())
I prefer the following which:
Allows you to use the Date column without calling a function on it. This is important for sargability i.e. the ability for SQL Server to use an index on the Date column. Although in my testing a cast to date still did you use the index, its best practice to avoid functions calls on the columns in where clauses.
Avoids the use of between, which I always have to take a moment to think about because its >= the first condition and <= the second condition. So its easy to get the logic wrong and include 8 days instead of 7. Instead I always use an explicit compare so its obvious what the logic is.
Note the >= and < now rather than <=.
where [Date] >= convert(date,dateadd(week, -3, current_timestamp))
and [Date] < convert(date,dateadd(week, -2, current_timestamp))
Now
Start Of Week (Inc)
End Of Week (Ex)
2020-12-29 20:07:16.373
2020-12-08
2020-12-15
And if you need it to start on your week start day then use:
where [Date] >= convert(date,dateadd(day, (-1*datepart(weekday,current_timestamp))+1, dateadd(week, -3, current_timestamp)))
and [Date] < convert(date,dateadd(day, (-1*datepart(weekday,current_timestamp))+1, dateadd(week, -2, current_timestamp)))
Now
Start Of Week (Inc)
End Of Week (Ex)
2020-12-29 20:07:16.373
2020-12-06
2020-12-13
That is only going to give you data that has a date that was three weeks ago from the current time to the nearest thousandth of a second. It's fairly unlikely that you have any data that exactly matches that.
What I expect you are after is data that is between three and two weeks ago which can be obtained like this:
WHERE date BETWEEN DATEADD(week, -3, GETDATE()) AND DATEADD(week, -2, GETDATE())
However if you run that half way through a day, it will only give you data from half way through the day three weeks ago until half way through the day two weeks ago. You probably want to go from midnight at the start and end of the day. This can be done by casting everything to the DATE type, which has the effect of discarding the time, like this:
WHERE CAST(date AS DATE) >= CAST(DATEADD(week, -3, GETDATE()) AS DATE) AND CAST(date AS DATE) < CAST(DATEADD(week, -2, GETDATE()) AS DATE)
It is also possible that you want to have the weeks always start on the same day of the week. This can be done using the DATEPART function.
WHERE DATEPART(week, date) = DATEPART(week, DATEADD(week, -3, GETDATE())) AND DATEPART(year, date) = DATEPART(year, DATEADD(week, -3, GETDATE()))
Depending upon what you want and how your database is set up this last option may require setting the SET DATEFIRST setting to get the correct day to start the week on. For example to start the week on Mondays use:
SET DATEFIRST 1;

How to retrieve records that are from two months from the current date

So what I am trying to do is when I run the query, I want to return all records that were in the month two months from the current month. For example, lets say the current month is November, when the query runs, I want returned all records from September and only September. If I run the query in lets say October, I want all records from August and only August. I am trying to do this in MS SQL. Thanks for any advice.
In SQL Server, you can use:
where datecol >= dateadd(month, -3, datefromparts(year(getdate()), month(getdate()), 1)) and
datecol < dateadd(month, -2, datefromparts(year(getdate()), month(getdate()), 1))
This is index- and optimizer- friendly. If you don't care about performance, you can use datediff():
where datediff(month, datecol, getdate()) = 2
This can be done in a nice 1 liner.
WHERE NOW() BETWEEN Date1 AND Date2;
You can have the month part in a variable and then it can be used in the Where clause to filter the month part of the date value is equal to the varoable value.
Query
Declare #month as int;
Set #month=datepart(month, getdate()) - 2;
Select * from yourTableName
Where month(dateCol) = #month;
The function GETDATE() can be used to retrieve the current month.
The function DATEADD(datepart,number,date) can be used to perform operations on dates. For more info look at the official docs
Thus, to retrieve the records from two months before (-2) the current month you can use the following:
DATEADD(month, -2, GETDATE())
In conclusion an example query to select all records that were in the month two months from the current month:
SELECT * FROM table
WHERE MONTH(month_column) = DATEADD(month, -2, GETDATE())
sources:
WHERE Clause to find all records in a specific month
SQL query for today's date minus two months

SQL Date Diff disregarding Year

i want to make a select, where the users birthday(date field) is less than 30 days.
what is the best way to to do it? i tried datediff, but i don't know how to put the year aside.
Thanks
You could just use DATEPART function with dayofyear datepart value.
EDIT: honestly, there is a boundary issue in my previous answer (many thanks to Damien): e.g. 2010-12-25 and 2011-01-07 => the difference should be less then 30 days, but DATEPART(dayofyear, #date) - DATEPART(dayofyear, [Birthday]) < 30 condition would skip this record. So I added an additional contition to my answer:
DATEPART(dy, #d) - DATEPART(dy, [Birthday]) < 30 OR
(
DATEPART(mm, #d) = 12 AND
DATEPART(dy, DATEADD(m, 1, #d)) - DATEPART(dy, DATEADD(m, 1, [Birthday])) < 30
)
it adds one month to the each date in the case when the month part of the first date is December and compares the difference.
A common way is to compose a formatted date, as text, and replace the year with the current year; and parse back into a date. Apply datediff on that.
If you find out datediff returns something negative thus the birthday of this year is in the past, add 1 year, and try again. This is for the time period around New Year.
SELECT *
FROM dbo.CheckBirthDay
WHERE (CASE WHEN YEAR(BirthDay) <= YEAR(CURRENT_TIMESTAMP) THEN DATEDIFF(DD,BirthDay,CURRENT_TIMESTAMP) END < 30 )