How to pass variable of adding 270 days to the date? - sql

Below is my query:
select
facility_lob as FACILITY_LOB,
TO_DATE(REPLACE(posting_d_date_sk, ',', ''), 'YYYYMMDD') as PostingDate,
count(distinct encounter_num ||cast(date_of_service as varchar(20) )) as ENCOUNTER_VOLUME,
SUM(charge_amt) as Gross_Charges
from sources.Table
where 1=1
and REPLACE(posting_d_date_sk, ',', '') >= '20210101'
and REPLACE(posting_d_date_sk, ',', '') <= '20210928'
and posting_d_date_sk <> '-1'
and posting_d_date_sk is not NULL
group by facility_lob, posting_d_date_sk
order by REPLACE(posting_d_date_sk, ',', '')
For now, I have hard coded the dates from Jan 1, 2021 to Sep 28, 2021 ( which is 270 days from Jan 1, 2021).
My requirement is the query should should pull data from and greater than year 2021 (>= 2021 of the posting date), and I need to pull the data from Jan 1, 2021, to 270 days. If I run the query today, I need to get the data from Jan 1, 2021 to Sep 28 2021 ( which is 270 days from jan 1 2021). If I execute this query tomorrow, I need to get the data from Jan 2 2021 to Sep 29 2021. jan 3, 2021 to sep 30 2021 etc.. If I run the query on April 3, 2022 then the calculation of 270 days is from Feb 1, 2021, to Oct 29, 2021.
Could you please help how do I fix this?

Why not using a simple dateadd based on getdate and then format it into your format ?
Declare #to varchar(10), #from varchar(10), #mydate smalldatetime
Set #mydate = Getdate()
Set #from = convert(varchar,year(#mydate)) + right('0' + convert(varchar,month(#mydate)),2) + right('0' + convert(varchar,day(#mydate)),2)
Set #mydate = dateadd(dd,270,getdate())
Set #to = convert(varchar,year(#mydate)) + right('0' + convert(varchar,month(#mydate)),2) + right('0' + convert(varchar,day(#mydate)),2)

Related

Subtract N from weeknum of current year

We have table WeeklyResults that looks like this:
Year WeekNum Value
2021 47 11.0
2021 48 14.0
2021 49 12.0
2021 50 17.0
2021 51 11.8
2021 52 11.3
2021 53 11.1
2022 01 11.5
2022 02 11.5
2022 03 81.5
We have a report with two parameters: Date and WeekNum. The report needs to show the last 6 weeks based on the weeknumber selected.
The issue is that, if user selects Week 2 of 2022, how can I subtract 6 weeks so that I get weeks 50, 51, 52, 53 of 2021 and weeks 1, 2 from 2022?
So, if the user selects 2022 and Week 02, it would show the last 6 weeks based on Weeknum 2 of year 2022 (wk50 to Wk02). If user selects 2021 and 52, it would show wk47-52.
You can use a little < and <= logic along side TOP and ORDER BY to achieve this:
DECLARE #Year int = 2022,
#WeekNum int = 3; --Note, if you are storing WeekNum as a (var)char,
--your leading zeros imply you are, then define the
--variable as a char(2).
SELECT TOP (6)
[Year],
WeekNum,
[Value]
FROM dbo.YourTable
WHERE ([Year] = #Year AND WeekNum <= #WeekNum)
OR [Year] < #Year
ORDER BY [Year] DESC,
WeekNum DESC;
Try this:
DECLARE #Year int = 2022
, #WeekNum varchar(02) = '02'
;
WITH FinalTable AS
(
SELECT TOP 6 *
FROM WeeklyResults
ORDER BY LTRIM(Year) + WeekNum DESC
)
SELECT *
FROM FinalTable
ORDER BY Year, WeekNum
Another option that doesn't involve an ORDER BY. Using DATEPART you can determine the final week of the prior year and subtract the number of weeks to get the records needed.
You may need to adjust what day is the first day of the week for your count. See this post for more info on that.
DECLARE
#Year INT = 2022
, #WeekNum INT = 3;
SELECT
*
FROM
WeeklyResults
WHERE
Year = #Year
AND WeekNum <= #WeekNum
OR
(
#WeekNum < 6
AND Year = #Year - 1
AND WeekNum > DATEPART (WEEK, CONCAT ('12/31/', #Year - 1)) - #WeekNum
);

-SQL - Get date up to present date and year

i'm trying to get the date from the start up to present date and year.
For example:
Date Today Jan 31 , 2020
the result must be
jan 1 - 31 2020 ,
Another example: if the date is june 30, 2020
the result must be
jan 1 - june 30, 2020
Can you help me how to do it ? , i'm planning to use BETWEEN
DECLARE #date date = ' 2019-05-01'
SELECT EOMONTH(#date), DATEADD(yy, DATEDIFF(yy, 0, #date), 0)

How to get financial quarters date by current date

The quarters described as below:
APRIL - JUNE - Q1
JULY - SEPT - Q2
OCT - DEC - Q3
JAN - MARCH - Q4
For ex:
Date = '2018-12-24' -- Where this date is under third quarter
So Expected should be [Get all quarter < current date's quarter]
---------------------------
Quarters
---------------------------
01 Jul 2018 - 30 Sep 2018
01 Apr 2018 - 30 Jun 2018
---------------------------
If the
Date = '2019-01-24' -- Where this date is under fourth quarter
Expected result:
---------------------------
Quarters
---------------------------
01 Oct 2018 - 30 Dec 2018
01 Jul 2018 - 30 Sep 2018
01 Apr 2018 - 30 Jun 2018
---------------------------
The query that I have tried:
DECLARE #dt DATETIME = '2019-01-24 18:15:59.517'
DECLARE #FirstDayOfQuarter DATETIME
DECLARE #LastDayOfQuarter DATETIME
SET #FirstDayOfQuarter = (SELECT Dateadd(qq, Datediff(qq, 0, #dt) - 1, 0))
SET #LastDayOfQuarter = (SELECT Dateadd(dd, -1, Dateadd(qq, Datediff(qq, 0, #dt)
, 0)))
DECLARE #year INT
SET #year = Datepart(year, #dt)
DECLARE #currQ NVARCHAR(max)
SET #currQ = (SELECT CONVERT(VARCHAR(20), #FirstDayOfQuarter, 106)
+ Space(1) + '-' + Space(1)
+ CONVERT(VARCHAR(20), #LastDayOfQuarter, 106))
SELECT CONVERT(NVARCHAR(20), Dateadd(m, 3*number, CONVERT(DATE, CONVERT(VARCHAR(
5),
#year)+'-1-1')), 106)
+ Space(1) + '-' + Space(1)
+ CONVERT(NVARCHAR(20), Dateadd(d, -1, Dateadd(m, 3*number+3, CONVERT(
DATE,
CONVERT(VARCHAR(5), #year)+'-1-1'))), 106) AS Quarter,
number,
CASE
WHEN #dt BETWEEN Dateadd(m, 3 * number, CONVERT(DATE, CONVERT(VARCHAR(5
),
#year) +
'-1-1')) AND
Dateadd(d, -1, Dateadd(m, 3 * number + 3,
CONVERT(DATE, CONVERT(VARCHAR(5)
,
#year
) + '-1-1'))) THEN 1
ELSE 0
END AS isCurrentQuarter
INTO #allquarters
FROM master..spt_values
WHERE type = 'p'
AND number BETWEEN 1 AND 4
SELECT TOP 1 number,
CASE
WHEN #dt BETWEEN Dateadd(m, 3 * number,
CONVERT(DATE, CONVERT(VARCHAR(5),
#year) +
'-1-1')) AND
Dateadd(d, -1, Dateadd(m, 3 * number + 3,
CONVERT(DATE, CONVERT(
VARCHAR(5),
#year
) + '-1-1'))) THEN 1
ELSE 0
END AS isCurrentQuarter
INTO #currentquarter
FROM master..spt_values
WHERE type = 'p'
AND number BETWEEN 1 AND 4
ORDER BY iscurrentquarter DESC,
number ASC
SELECT quarter
FROM #allquarters
WHERE number < (SELECT number
FROM #currentquarter)
ORDER BY number DESC
DROP TABLE #allquarters
DROP TABLE #currentquarter
It is working for GETDATE() but when I put the date as 2019-01-24 18:15:59.517 then it gives me empty result
EDIT:
If the
Date = '2019-05-24' -- Where this date is under first quarter of next year
Expected result:
---------------------------
Quarters
---------------------------
01 Jan 2019 - 30 March 2019
01 Oct 2018 - 30 Dec 2018
01 Jul 2018 - 30 Sep 2018
01 Apr 2018 - 30 Jun 2018
---------------------------
If the
Date = '2018-05-24' -- Where this date is under the first quarter of current year
Expected result:
---------------------------
Quarters
---------------------------
01 Jan 2018 - 30 March 2018
01 Oct 2017 - 30 Dec 2017
01 Jul 2017 - 30 Sep 2017
01 Apr 2017 - 30 Jun 2017
---------------------------
I believe this does what you want:
with dte as (
select cast('2019-07-24' as date) as dte
)
select dte,
(convert(varchar(255), dateadd(month, v.n, datefromparts(year(dte), ((month(dte) - 1) / 3) * 3 + 1, 1)), 106) + ' - ' +
convert(varchar(255), dateadd(day, -1, dateadd(month, v.n + 3, datefromparts(year(dte), ((month(dte) - 1) / 3) * 3 + 1, 1))), 106)
) as string
from dte cross apply
(values (0), (-3), (-6), (-9)) v(n)
where month(dte) < 4 or month(dte) >= 13 + v.n
order by v.n;
Here is a db<>fiddle.
Use the formula (n + 5) % 12 + 3 to convert month numbers 1, 2, ..., 12 to 9, 10, ..., 14, 3, ..., 8 which is the number of months you need to subtract from a given date. In SQL Server 2008 you would translate it as:
DATEADD(MONTH, DATEDIFF(MONTH, 0, inputdate) - ((MONTH(inputdate) + 5) % 12 + 3), 0)
The converts 2018-04-xx to 2017-04-01 and 2018-07-xx to 2018-04-01. Adding 3, 6 and 9 months is trivial.
DB Fiddle

How to SUM over month columns in past year best way?

I have following columns from Jan to Dec:
Year - Jan - Feb - Mar - (etc.) - Dec
---- --- --- --- ---
2015 25 32 102 12
2016 30 40 50 60
How to effectively do SUM over past year? Let's say from GETDATE(), If today is 16.08.2017, I want SUM from 16.08.2016 (from august 2016 till august 2017).
I have following code:
select sum(val)
from t cross apply
(values (t.year, t.Jan, 1),
(t.year, t.Feb, 2),
. . .
) v(yyyy, val, mon)
where yyyy * 100 + mon >= (year(getdate()) - 1) * 100 + month(getdate());
which works, but is there any way to do it without cross apply? (for instance: just where clause)
how about something like below which uses UNPIVOT notation.
select sum(val)
from
(select * from t )s
unpivot
( val for month in ( Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec))up
where
cast(month+ cast(year as varchar(20)) as date)
between dateadd(m,-12,getdate()) and getdate()
Live Demo
Assuming all your column month names are 3 letters, you could also use dynamic SQL. Something like the following should work.
DECLARE #CurrentDate DATE = CAST(GETDATE() AS DATE)
DECLARE #Year INT = DATEPART(YEAR, #CurrentDate)
DECLARE #PrevYear INT = #Year - 1
DECLARE #Month CHAR(3)
SET #Month = convert(char(3), #CurrentDate, 0)
BEGIN
EXEC('SELECT SUM(t.'+#Month+') FROM t WHERE Year >= ' + #PrevYear + ' AND Year <= ' + #Year)
END

How do I build ISO Week Number table programatically in T-SQL query?

Anyone knows how to built temp table of week using T-SQL query?
I heard there has a lot of type of calculations for that, Gregorian or etc... My needs are ISO Week No and bind to temp table depends on week no.
The temp table has 2 columns : ISOWeekNo and WeekName
ISOWeekNo WeekName
1 01 Jan 2013 To 07 Jan 2013
2 08 Jan 2013 To 14 Jan 2013
How do I build programmatically in T-SQL Query based on ISO Week No?
Updated : I want to pass the parameter year only. e.g : 2013
EDIT: Added WHERE clause to terminate for sought year only.
This seems to match the Wikipedia description and I am sure there is room for optimisation.
Mikael, I copied your formatting code for the friendly column, thank you.
This code will work on SQL Server 2008 onwards because of the use of the ISOWEEK datepart.
use tempdb
go
DECLARE #Year SMALLINT = 2013
,#FirstISOWKDay DATETIME
;WITH FindISOWEEKFirstDay AS
(
SELECT DT = DATEADD(DAY, -7, DATEFROMPARTS(#Year, 1, 1))
UNION ALL
SELECT DATEADD(DAY, 1, DT)
FROM FindISOWEEKFirstDay
WHERE DATEADD(DAY, 1, DT) < DATEADD(DAY, 14, DATEFROMPARTS(#Year, 1, 1))
)
SELECT TOP 1 #FirstISOWKDay = DT
FROM FindISOWEEKFirstDay
WHERE DATEPART(ISO_WEEK, DT) = 1
ORDER BY DT ASC -- Eliminate probability of arb sorting (Thanks Mikael)
;WITH Base10 (n) AS
(
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1
)
,Base1000 (n) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))-1
FROM Base10 T1, Base10 T2, Base10 T3
)
SELECT Start = DATEADD(DAY, n*7, #FirstISOWKDay)
,[End] = DATEADD(DAY, n*7 + 6, #FirstISOWKDay)
,Friendly = CONVERT(VARCHAR(101), DATEADD(DAY, n*7, #FirstISOWKDay), 106)+' To '+CONVERT(VARCHAR(101), DATEADD(DAY, n*7 + 6, #FirstISOWKDay), 106)
,ISOWEEK = DATEPART(ISO_WEEK, DATEADD(DAY, n*7, #FirstISOWKDay))
FROM Base1000
-- Filter to terminate, resulting only in sought year's calendar
WHERE DATEPART(YEAR, DATEADD(DAY, n*7 + 6, #FirstISOWKDay)) = #Year
declare #Year int;
set #Year = 2016;
with C as
(
select datefromparts(#Year, 1, 1) as D
union all
select dateadd(day, 1, C.D)
from C
where C.D < datefromparts(#Year, 12, 31)
)
select datepart(iso_week, C.D) as ISOWeekNo,
convert(varchar(101), min(C.D), 106)+' To '+convert(varchar(101), max(C.D), 106) as WeekName
from C
group by datepart(iso_week, C.D),
case when datepart(month, C.D) = 12 and
datepart(iso_week, C.D) > 50
then 1
else 0
end
order by min(C.D)
option (maxrecursion 0);
Result:
ISOWeekNo WeekName
----------- --------------------------
53 01 Jan 2016 To 03 Jan 2016
1 04 Jan 2016 To 10 Jan 2016
2 11 Jan 2016 To 17 Jan 2016
3 18 Jan 2016 To 24 Jan 2016
4 25 Jan 2016 To 31 Jan 2016
5 01 Feb 2016 To 07 Feb 2016
6 08 Feb 2016 To 14 Feb 2016
7 15 Feb 2016 To 21 Feb 2016
.
.
.
47 21 Nov 2016 To 27 Nov 2016
48 28 Nov 2016 To 04 Dec 2016
49 05 Dec 2016 To 11 Dec 2016
50 12 Dec 2016 To 18 Dec 2016
51 19 Dec 2016 To 25 Dec 2016
52 26 Dec 2016 To 31 Dec 2016
This may help:
Select date '2012-12-31' + level*7 WK_STARTS_DT
, to_char(date '2012-12-31' + level*7, 'IW') ISO_WEEK
, to_char(date '2012-12-31' + level*7, 'WW') WEEK
From dual
Connect By Level <=
(
Select Round( (ADD_MONTHS(TRUNC(SYSDATE,'Y'),12)-TRUNC(SYSDATE,'Y') )/7, 0) From dual
) --365/7
/
WK_STARTS_DT ISO_WEEK WEEK
------------------------------------
1/7/2013 02 01
1/14/2013 03 02
1/21/2013 04 03
......
2/4/2013 06 05
2/11/2013 07 06
......
3/4/2013 10 09
To confirm week numbers:
http://www.epochconverter.com/date-and-time/weeknumbers-by-year.php?year=2013