Current Month, Previous Month, Next Month - sql

This is my query
select *
from RDR1 A
where Year(A.shipdate) = '2021'
and (
Month(A.shipdate) = Month(CURRENT_TIMESTAMP) - 1
or Month(A.shipdate) = Month(CURRENT_TIMESTAMP) + 1
or Month(A.shipdate) = Month(CURRENT_TIMESTAMP)
)
The above query works fine when they choose the year 2020, But when they choose 2021 it doesn't work. The above query should filter based on the current month. For eg: December 2020 (Current Month), Jan 2021 (next month), November (Previous Month).
How should I modify my query?

If you want the last month, this month, or next month, I would suggest:
where a.shipdate >= dateadd(month, -1, datefromparts(year(getdate()), month(getdate()), 1)) and
a.shipdate < dateadd(month, 2, datefromparts(year(getdate()), month(getdate()), 1))
This is index-friendly. If that is not a concern, you can use:
where datediff(month, s.shipdate, getdate()) between -1 and 1

Related

SQL query to find dates of last year equivalent to today's date

I am writing a SQL query to find business working dates of last year equivalent to today's date.
In this query it should fetch :-
For e.g. if today is 5th January, 2021 and it is the second day of second week of the year. So I need to find the exact equivalent date of the second day of second week of the previous year. So it would be 7th January, 2020.
And with this, I need the business working dates of that week of 7th January 2020 (i.e. excluding Saturday & Sunday)
Which will come up as 2020-Jan-06 to 2020-Jan-10 according to the example.
So I will need the report between 6th Jan - 10th Jan, 2020.
I am trying to use this code to find date of last year equivalent to today's date (5th Jan, 2021 viz. second day of second week)
select Convert(date, (DATEADD(year, -1, getdate()+2))) ;
2021-01-05 is the 2nd day of the first week of 2021 according to ISO standards.
If you want the 2nd day of the first week of 2021, then it is either today's date minus 52 weeks or 53 weeks. Based on the Wikipedia page for ISO dates:
[53 week years are those] years in which 1 January or 31 December are Thursdays
So, we want that for the previous year. Hence, I think the following should work:
select dateadd(week,
(case when 'Thursday' in (datename(weekday, datefromparts(year(getdate()) - 1, 1, 1)),
datename(weekday, datefromparts(year(getdate()) - 1, 12, 31))
)
then -53 else -52
end),
convert(date, getdate())
)
Note that this returns 2019-12-31, which is the correct value based on ISO standards.
I have use multiple CTE to show you the step by step calculation. It should be pretty easy to follow.
Basically it find the week_no and day_no_of_week for 2021-01-05 and then use that to find the same date for 2020
declare #input_date date = '2021-01-05',
#year_offset int = -1; -- previous year
with
cte1 as
(
select input_date = #input_date,
week_no = DATEPART(WEEK, #input_date),
first_day_of_week = DATEADD(WEEK, DATEDIFF(WEEK, 0, #input_date), 0)
),
cte2 as
(
select *,
day_no_of_week = DATEDIFF(DAY, first_day_of_week, #input_date) + 1
from cte1
),
cte3 as
(
select *,
first_day_of_the_prev_year = DATEADD(YEAR, DATEDIFF(YEAR, 0, #input_date) + #year_offset, 0)
from cte2
),
cte4 as
(
select *,
first_day_of_week_prev_year = DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(WEEK, week_no - 1, first_day_of_the_prev_year)), 0)
from cte3
)
select *,
DATEADD(DAY, day_no_of_week - 1, first_day_of_week_prev_year) as the_required_date
from cte4

Last Day of Each Month Calculation

I have a table X which holds data for each day for a brand. The data for each day is cumulative i.e. sales data for 3 will have data for 1, 2 and 3. Thus data for the last day of each month will be the sales for that month for that brand and company. I want to get the sum of all the sales for that brand for the last 3 months excluding the current month on the last day of each month.
i.e for March: I want sales from 31st Jan 2019 + 28th Feb 2019 + 31st Dec 2018 for each brand and company.
How can I achieve this?
if you are using MSSQL you can use EOMONTH function, example is as under
DECLARE #date VARCHAR(255) = '2/24/2019';
SELECT EOMONTH ( #date ) AS Result;
for MySQL you can use LAST_DAY function
SELECT LAST_DAY('2019-02-24');
Let's say name of your column representing the sales date is "sales_date", then the following predicate will give you the days you're interested in:
sales_date in (
dateadd(day, -1, dateadd(month, datediff(month, 0, getdate()) - 2, 0)),
dateadd(day, -1, dateadd(month, datediff(month, 0, getdate()) - 1, 0)),
dateadd(day, -1, dateadd(month, datediff(month, 0, getdate()), 0))
)

How to calculate a date column based on other 2 attributes?

I have to calculate a date field in run time based on 2 other fields.
----------------------------------------------------------
Run Date || Schedule || Next Bill run date
-----------------------------[enter image description here][1]-----------------------------
----------------------------------------------------------
11/29/2018 || 1st || 12/01/2018
----------------------------------------------------------
11/29/2018 || 15th || 12/15/2018
----------------------------------------------------------
12/02/2018 || 1st || 12/01/2019
----------------------------------------------------------
12/02/2018 || 15th || 12/15/2018
----------------------------------------------------------
12/16/2018 || 15th || 01/15/2019
----------------------------------------------------------
In the above scenario Next bill Run date should be populated based on the previous 2 column.
There are 4 conditions are there,
if the day(Run_date) between 2nd-15th of the same month and value of schedule is '15th' then "Next Bill Run" will be 15th of the same month.
if the day(Run_date) between 16th(same month) - 1st(next month) and value of schedule is '15th' then "Next Bill Run" will be 15th of the next month.
if the day(Run_date) between 2nd-15th of the same month and value of schedule is '1st' then "Next Bill Run" will be 1st of the next month.
if the day(Run_date) between 16th(same month) - 1st(next month) and value of schedule is '1st' then "Next Bill Run" will be 1st of the next month.
Please see the above table for better understanding. Please help me to find out a logic to implement "Next Bill Run". Appreciate your help.
I am thinking of using 'case' function to get the datepart() of the Run Date. But still confused with the implementation
Hope this below query will help you.
set #lastDate := (SELECT LAST_DAY(now()) AS first_day);
set #firstDate := (SELECT DATE_ADD(DATE_ADD(LAST_DAY(now()),INTERVAL 1 DAY),INTERVAL - 1 MONTH) AS first_day);
select run_date,schedule,
case
when run_date between #firstDate and DATE_ADD(#firstDate, INTERVAL 14 DAY) and schedule ='15th' then DATE_ADD(#firstDate, INTERVAL 14 DAY)
when run_date between DATE_ADD(#firstDate, INTERVAL 15 DAY) and DATE_ADD(#firstDate, INTERVAL 1 MONTH) and schedule ='15th' then date_add(DATE_ADD(#firstDate, INTERVAL 14 DAY), INTERVAL 1 MONTH)
when run_date between #firstDate and DATE_ADD(#firstDate, INTERVAL 14 DAY) and schedule ='1st' then DATE_ADD(#firstDate, INTERVAL 1 MONTH)
when run_date between DATE_ADD(#firstDate, INTERVAL 15 DAY) and DATE_ADD(#firstDate, INTERVAL 1 MONTH) and schedule ='1st' then DATE_ADD(#firstDate, INTERVAL 1 MONTH)
end
as next_bill_run_date
from your_table
in SQL Server
declare #firstDate as date = '01-'+month(getdate())+'-'+year(getdate());
select run_date,schedule,
case
when run_date between #firstDate and DATEADD(DAY,14,#firstDate) and schedule ='15th' then DATEADD(DAY,14,#firstDate)
when run_date between DATEADD(DAY,15,#firstDate) and DATEADD(MONTH, 1, #firstDate) and schedule ='15th' then DATEADD(MONTH, 1, DATEADD(DAY,14,#firstDate))
when run_date between DATEADD(DAY,14,#firstDate) and schedule ='1st' then DATEADD(MONTH, 1, #firstDate)
when run_date between DATEADD(DAY,15,#firstDate) and DATEADD(MONTH, 1 #firstDate) and schedule ='1st' then DATEADD(MONTH, 1 #firstDate)
end
as next_bill_run_date
from your_table
Yes, your logic is correct. Use the case statement along with some of the DATE functions in SQL SERVER. With my limited knowledge with SQL SERVER date functions i have framed the below query. You can still optimize this.
SELECT
RUN_DATE,SCHEDULE,
case
when (DATEPART(month,run_date)=month(sysdatetime()) --checking same month
and DATEPART(day, run_date) between 2 and 15 and Schedule='15th') --checking date between 2nd and 15th and schedule is 15th
then DATEADD(month, DATEDIFF(month, 0,run_date), 0)+14 --selecting 15th of same month
when (DATEPART(month,run_date)=month(sysdatetime())
and DATEPART(day, run_date) between 2 and 15 and Schedule='1st') --checking date between 2nd and 15th and schedule is 1st
then DATEADD(month, DATEDIFF(month, 0,run_date)+1, 0) --selecting 1st of next month
when (DATEPART(month,run_date)=month(sysdatetime()) or run_date=DATEADD(month, DATEDIFF(month, 0,run_date)+1,0))
and (((DATEPART(day, run_date) between 16 and 31) or (run_date=DATEADD(month, DATEDIFF(month, 0,run_date)+1,0)))
and Schedule='1st')
then case when (run_date=DATEADD(month, DATEDIFF(month, 0,run_date),0))
then
DATEADD(month, DATEDIFF(month, 0,run_date),0) -- if 1st of next month, select first day of same month
else
DATEADD(month, DATEDIFF(month, 0,run_date)+1,0) --selecting 1st of next month
end
when (DATEPART(month,run_date)=month(sysdatetime()) or run_date=DATEADD(month, DATEDIFF(month, 0,run_date),0))
and (((DATEPART(day, run_date) between 16 and 31) or (run_date=DATEADD(month, DATEDIFF(month, 0,run_date),0)))
and Schedule='15th')
then case when (run_date=DATEADD(month, DATEDIFF(month, 0,run_date),0))
then
DATEADD(month, DATEDIFF(month, 0,run_date),0)+14 -- if 1st of next month, select 15 of same month
else
DATEADD(month, DATEDIFF(month, 0,run_date)+1,0)+14 --selecting 15th of next month
end
end as NEXT_BILL_RUN_DATE
FROM mytable ;
case
when schedule='1st'
then DATEFROMPARTS(DATEPART(year, DATEADD(month, 1, RUN_DATE)), DATEPART(month, DATEADD(month, 1, RUN_DATE)), 01)
when schedule='15th' and DATEPART(day, RUN_DATE)>=15
then DATEFROMPARTS(DATEPART(year, DATEADD(month, 1, RUN_DATE)), DATEPART(month, DATEADD(month, 1,RUN_DATE)), 15)
when schedule='15th' and DATEPART(day, RUN_DATE)<15
then DATEFROMPARTS(DATEPART(year, RUN_DATE), DATEPART(month, RUN_DATE)), 15)
end AS NEXT_BILL_RUN_DATE

First date of current Fiscal Year

I am trying to get the First Date of the current Fiscal year. In my case the Fiscal year starts in Oct.
Example: I need the 10/01/2015
I would generally use the below query to the get the first day of the current year but how do I change it to get the first date of fiscal year?
select
convert(varchar(12), (
DateAdd(month, (
Month(getdate()) - 1) * -1,
DateAdd(Day, (
Day(getdate()) - 1) * -1,
getdate()))),
103) as StartYear
You can apply following logic: Subtract 9 months from the current date, find Jan 1st of this year and add 9 months again:
DATEADD(MONTH, 9, DATEADD(YEAR, DATEDIFF(YEAR, 0, DATEADD(MONTH, -9, GETDATE())), 0))
declare #fiscal date = '2015-10-01'
; with dates
as
(
select date = '2015-09-30' union all
select date = '2015-10-01' union all
select date = '2016-09-30' union all
select date = '2016-10-01'
)
select *,
fiscal = case when date < dateadd(year, year(date) - year(#fiscal), #fiscal)
then dateadd(year, year(date) - year(#fiscal) - 1, #fiscal)
else dateadd(year, year(date) - year(#fiscal), #fiscal)
end
from dates
/* result
date fiscal
---------- ----------
2015-09-30 2014-10-01
2015-10-01 2015-10-01
2016-09-30 2015-10-01
2016-10-01 2016-10-01
*/
At first Subtract 9 months from current date to get the previous year(your Fasical year).
Then take the year difference with 0 to your date.
Now add the year difference with 0 to get the starting of a month.
Finally you need to add the 9 months to get the starting month of a Fasical Year.
As year example the require format "10/01/2015". So get that you can use convert function with 101.
select convert(varchar(12), DATEADD(MONTH, 9, DATEADD(YEAR, DATEDIFF(YEAR, 0, DATEADD(MONTH, -9, GETDATE())), 0)), 101) as StartYear

SQL: Selecting current month last year

I currently select data from the current month LAST year. This works fine with
SELECT cast(CREATED as date) AS DATE, COUNT([ID]) AS BOOKINGS, SUM([TOTCOST]) AS Sales
from BOOKING
WHERE
CREATED >= DATEADD(month, datediff(month, 0, getdate())-12, 0)
AND
CREATED < DATEADD(month, datediff(month, 0, getdate())-11, 0)
GROUP BY cast(CREATED as date)
ORDER BY cast(CREATED as date)
However, rather than return 1st to 31st July, I would like to return 2nd July 2014 to 1st August 2014 inclusive. So effectivly +1 day on that current month.
Is this possible?
Yes, simply add 1 to the result of your calculation.
SELECT cast(CREATED as date) AS DATE, COUNT([ID]) AS BOOKINGS, SUM([TOTCOST]) AS Sales
from BOOKING
WHERE
CREATED >= (DATEADD(month, datediff(month, 0, getdate())-12, 0) + 1)
AND
CREATED < (DATEADD(month, datediff(month, 0, getdate())-11, 0) + 1)
GROUP BY cast(CREATED as date)
ORDER BY cast(CREATED as date)