Integer key to date in a named calculation - ssas

Trying to do a named calculation in SSAS from a integer key to Quarter.
IntegerDateKey Below:
SalesDateKey
20100101
20100101
20100101
20100102
20100102
20100102
20100102
This doesn't work and no matter how I cast it, I can't get it to work.
CONVERT(char(4), YEAR(SalesDateKey))+
CASE
WHEN MONTH(SalesDateKey) BETWEEN 1 AND 3 THEN 'Q1'
WHEN MONTH(SalesDateKey) BETWEEN 4 AND 6 THEN 'Q2'
WHEN MONTH(SalesDateKey) BETWEEN 7 AND 9 THEN 'Q3'
ELSE 'Q4'
END
Any help would be greatly appreciated. Please test your findings on a named calculation in SSAS.

Figured it out!
CAST(DATEPART(YEAR, CAST(CAST(SalesDateKey AS char(8)) AS DateTime)) AS
VARCHAR(4)) + ' - ' +
CASE
WHEN Month(CAST(CAST(SalesDateKey AS CHAR(8)) AS DATE)) BETWEEN 1 AND 3
THEN 'Q1'
WHEN Month(CAST(CAST(SalesDateKey AS CHAR(8)) AS DATE)) BETWEEN 4 AND 6
THEN 'Q2'
WHEN Month(CAST(CAST(SalesDateKey AS CHAR(8)) AS DATE)) BETWEEN 7 AND 9
THEN 'Q3'
ELSE 'Q4'
END

Related

SQL - How to determine fiscal quarter when quarters are determined by # of days?

I have a situation I've never seen before, where a fiscal year started on 2/4/2018 is broken down like this:
Q1 - 111 days long (2/4/2018 - 5/26/2018)
Q2 - 83 days long (5/27/2018 - 8/18/2018)
Q3 - 83 days long (8/19/2018 - 11/10/2018)
Q4 - 83 days long (11/11/2018 - 2/2/2019)
That is considered FY 2018
The next year, FY 2019, starts on 2/3/2019 and has the same quarter lengths, and Q4 would end on 2/1/2020. FY 2020 then starts on 2/2/2020.
I need to be able to determine the fiscal year and quarter for a given date (#testdate in my code below). The following works for FY 2018:
declare #startdate date = '2/4/2018'
, #startyear int = 2018
, #testdate date = '2/5/2018'
select 'Fiscal Year' = case when datediff(dd, #startdate, #testdate) between 0 and 363 then #startyear else 0 end
select 'Fiscal Quarter' = case when datediff(dd, #startdate, #testdate) between 0 and 111 then 'Q1'
when datediff(dd, #startdate, #testdate) between 112 and 195 then 'Q2'
when datediff(dd, #startdate, #testdate) between 196 and 279 then 'Q3'
when datediff(dd, #startdate, #testdate) between 280 and 363 then 'Q4'
else 'Q0' end
The problem is when I have a date after the end of FY 2018 Q4 (2/2/2019). I'm not sure how to get any date past that to automatically fall into the day ranges (0-111, 112-195, 196-279, 280-363). Manually, for FY 2019, I can subtract 364 from the date and that seems to work. For FY 2020, I can subtract 364 * 2 (728). For each year after that, keep subtracting 364 * n where n is the number of years between whatever future fiscal year and FY 2018.
This works for FY 2020:
declare #startdate date = '2/4/2018'
, #startyear int = 2018
, #testdate date = '5/28/2020'
, #testdate2 date = null
set #testdate2 = dateadd(d, -728, #testdate)
select 'Fiscal Year' = case when datediff(dd, #startdate, #testdate2) between 0 and 363 then #startyear + 2 else 0 end
select 'Fiscal Quarter' = case when datediff(dd, #startdate, #testdate2) between 0 and 111 then 'Q1'
when datediff(dd, #startdate, #testdate2) between 112 and 195 then 'Q2'
when datediff(dd, #startdate, #testdate2) between 196 and 279 then 'Q3'
when datediff(dd, #startdate, #testdate2) between 280 and 363 then 'Q4'
else 'Q0' end
I'm guessing the solution revolves around how to calculate that -728 automatically (which would be 364 * n), and how to increment #startyear accordingly.
Any ideas on how to determine the fiscal year and quarter for a given date with these odd fiscal quarters?
Thanks!
Here is a solution which does an integer division to get the number of years after 2018. We then subtract 364 times this number from DATEDIFF the base year to get the number of days from the start of the current tax year. We can use your case statement to determine the quarter.
create function dbo.quarter (#date date)
returns varchar(100)
as
begin
declare #days int = datediff(dd,'2018-04-02',#date)
declare #years int = #days / 364
set #days = #days - (#years * 364)
set #years = #years + 2018
declare #quarter char(2)= case
when #days between 0 and 111 then 'Q1'
when #days between 112 and 195 then 'Q2'
when #days between 196 and 279 then 'Q3'
when #days between 280 and 363 then 'Q4'
else 'Q0' end
return concat(#years,'-', #quarter)
end
GO
✓
select dbo.quarter('5/4/2018') quarter;
select dbo.quarter('2020-04-02') quarter;
select dbo.quarter('2022-01-24') quarter;
select dbo.quarter(GETDATE()) quarter;
select dbo.quarter('2021-12-25') quarter;
GO
| quarter |
| :------ |
| 2018-Q1 |
| quarter |
| :------ |
| 2020-Q1 |
| quarter |
| :------ |
| 2021-Q4 |
| quarter |
| :------ |
| 2021-Q4 |
| quarter |
| :------ |
| 2021-Q3 |
db<>fiddle here

How to compare date (yyyy-mm-dd) with year-Quarter (yyyyQQ) in python

I am writing a sql query using pandas within python. In the where clause I need to compare a date column (say review date 2016-10-21) with this value '2016Q4'. In other words if the review dates fall in or after Q4 in 2016 then they will be selected. Now how do I convert the review date to something comparable to 'yyyyQ4' format. Is there any python function for that ? If not, how so I go about writing one for this purpose ?
Once you are able to get the month out into a variable: mon
you can use the following code to get the quarter information:
for mon in range(1, 13):
print (mon-1)//3 + 1,
print
which would return:
for months 1 - 3 : 1
for months 4 - 6 : 2
for months 7 - 9 : 3
for months 10 - 12 : 4
Id suggest converting your Review date to a quarter format. Then checking if they are equal.
Example
SELECT (CONVERT(VARCHAR(4),DATEPART(YYYY, GETDATE())) + 'Q' +
CASE
WHEN CONVERT(VARCHAR(2),DATEPART(M,GETDATE())) <= 3 THEN '1'
WHEN CONVERT(VARCHAR(2),DATEPART(M,GETDATE())) <= 6 THEN '2'
WHEN CONVERT(VARCHAR(2),DATEPART(M,GETDATE())) <= 9 THEN '3'
WHEN CONVERT(VARCHAR(2),DATEPART(M,GETDATE())) <= 12 THEN '4'
END)
You can use that in a where like this, just replace GETDATE() with your review date column and '2018Q1' with your quarter column
WHERE (CONVERT(VARCHAR(4),DATEPART(YYYY, GETDATE())) + CASE
WHEN CONVERT(VARCHAR(2),DATEPART(M,GETDATE())) <= 3 THEN 'Q1'
WHEN CONVERT(VARCHAR(2),DATEPART(M,GETDATE())) <= 6 THEN 'Q2'
WHEN CONVERT(VARCHAR(2),DATEPART(M,GETDATE())) <= 9 THEN 'Q3'
WHEN CONVERT(VARCHAR(2),DATEPART(M,GETDATE())) <= 12 THEN 'Q4'
END) = '2018Q1'

SQL - date range from current date to 2 years ago

I'm new here and kind of a noob to sql as well. I need help on this logic. The issue is in the "dateadd" function I believe. I need to get the date range of the current date (August 2014) to 2 years ago (August 2012). One of my mates said I could use a max function but he is not sure how to either. Not sure what to do..please guide me. Thanks!
--count of EDI exceptions daily with current status
select count(InvoiceUniqueness) as [Nbr], CONVERT(varchar(12), ProcessDate, 101) as [Date],
case currentstatus when 1 then 'production' when 2 then 'exception' when 3 then 'archive' end as [CurrentStatus]
from PreProcessTransLog
where (CONVERT(DATETIME, ProcessDate, 102)) >= dateadd (yy,-2,getdate()) and InitialStatus =2
group by CONVERT(varchar(12), ProcessDate, 101), currentstatus
order by CAST (CONVERT(varchar(12), ProcessDate, 101) as smalldatetime) desc
Results from the Query:
6 10/11/2014 production
12 10/10/2014 production
3 09/30/2014 production
2 09/28/2014 production
34 09/27/2014 production
39 09/26/2014 production
150 08/02/2014 exception
40 08/01/2014 production
62 08/01/2014 archive
437 08/01/2014 exception
60 07/31/2014 production
54 07/31/2014 archive
46 07/31/2014 exception
61 07/30/2014 exception
113 07/30/2014 production
98 07/30/2014 archive
7 07/29/2014 exception
130 07/29/2014 archive
80 07/29/2014 production
84 07/28/2014 production
....
....
....
As you can see I'm getting a dates after August like September and October. I just want to current date.
Thanks!!
Can you just add in ProcessDate <= today's date?
SELECT COUNT(InvoiceUniqueness) AS [Nbr] ,
CONVERT(VARCHAR(12), ProcessDate, 101) AS [Date] ,
CASE currentstatus
WHEN 1 THEN 'production'
WHEN 2 THEN 'exception'
WHEN 3 THEN 'archive'
END AS [CurrentStatus]
FROM PreProcessTransLog
WHERE CONVERT(DATETIME, ProcessDate, 102) >= DATEADD(yy, -2, GETDATE())
AND ProcessDate <= GETDATE()
AND InitialStatus = 2
GROUP BY CONVERT(VARCHAR(12), ProcessDate, 101) ,
currentstatus
ORDER BY CAST (CONVERT(VARCHAR(12), ProcessDate, 101) AS SMALLDATETIME) DESC

Get most recent 8PM via SQL

What's a good way to get the most recent 8 PM in SQL? For instance if it was 7/17 4 PM result would be 7/16 8PM, but if it was 7/17 9 PM it would be 7/17 8 PM.
Thanks!
I think so:
select (case when datepart(hour, getdate()) >= 20
then cast(cast(getdate() as date) as datetime) + 20.0/24
else cast(cast(getdate() - 1 as date) as datetime) + 20.0/24
end)

SQL date issue when date is not isdate

Expiry DateEnd
None 2000-06-29 00:00:00.000
None 2000-06-29 00:00:00.000
september 2013 2013-06-29 00:00:00.000
January 2012 2013-06-29 00:00:00.000
May 2020 2013-06-29 00:00:00.000
2013-06-29 00:00:00.000 2013-06-29 00:00:00.000
From two column I want pick all dates except May 2020 rows, due to future date.
this is what I have so far
DECLARE #YearFlag datetime
SET #YearFlag = DATEADD(yy,-5,GETDATE())
SELECT *
FROM #Table
WHERE (DateEnd IS NULL OR DateEnd = '' OR DateEnd <= #YearFlag)
OR (CHARINDEX(Convert(varchar, YEAR(GETDATE())),Expiry) > 0)
was using below one to pick January 2012 row but getting error
OR (Expiry != 'none' AND Expiry <= GETDATE())
I assume you want to exclude future dates from your select, so you can use something like this.
(also, please specify RDBMS because the GETDATE() function might not be available in the one you're using)
SELECT Expiry,
DateEnd
FROM YOUR_TABLE
WHERE Expiry <> 'none'
AND convert(INT, substring(expiry, charindex(' ', expiry, 0), len(expiry))) < YEAR(GETDATE())
AND CASE LOWER(substring(expiry, 0, charindex(' ', expiry, 0)))
WHEN 'january' THEN 1
WHEN 'february' THEN 2
WHEN 'march' THEN 3
WHEN 'april' THEN 4
WHEN 'may' THEN 5
WHEN 'june' THEN 6
WHEN 'july' THEN 7
WHEN 'august' THEN 8
WHEN 'september' THEN 9
WHEN 'october' THEN 10
WHEN 'november' THEN 11
ELSE 12
END < MONTH(GETDATE())
Here is a SQLFiddle with how the code works.