Custom Sort on DimCalendar - sql

I have a DimCalendar dimension and I want to create a custom column on top of this which will be used as a "Sort By Column" in PowerBI report.
The sorting order should be Jan 2015, Jan 2016, Jan 2017, Feb 2015, Feb 2016, Feb 2017 and so on.
Hence, can someone help me write a SQL statement to create a column which will rank the numbers in the above sorting order?
Thanks.
[UPDATE]
Sample data - I have taken only first two dates from entire month.

The customer sort can be set by using the year and month. In many databases, you can define it as:
update dimCalendar
set customsort = month(date) * 10000 + year(date);
The ANSI standard syntax would be:
update dimCalendar
set customsort = extract(month from date) * 10000 + extract(year from date);

You can concatenate year part and month part of date.
In Ms SQL server you can use
Datepart (year, date)+"/" + Datepart(month,date)

Related

Retrieve specific year in the format of "2019-05-04 11:20:22.697" in SQL query

How can I retrieve specific year in the format of “2019-05-04 11:20:22.697” in SQL query? I need the date between 2019 and 2020.
select * from date where date between '2019-01-01' and '2020-01-01'
If you want a query to just target the year 2019, then use:
SELECT *
FROM yourTable
WHERE date >= '2019-01-01' AND date < '2020-01-01';
This will include the entire 2019 calendar year, up to, but not including, January 1 of 2020. Note also that the above WHERE clause, as written, is sargable, meaning that the above query could take advantage of an index on the date column for doing the search.

How can I create a new column for Fiscal Year based on custom date ranges in SQL?

I'm looking to create a new column that includes fiscal year based on custom ranges of the Date of Distribution field (See my query below) in SQL. This is probably relatively simple but I've played around a bit with no luck.
Values I wish to create and range definitions:
FY20 = July 1, 2019 to June 30, 2020
FY21 = July 1, 2019 to June 30, 2020
A very simplified version of my current query:
Select
TRANSACTION_Table.DATE_OF_DISTRIBUTION
Datename(Month, TRANSACTION_Table.DATE_OF_DISTRIBUTION) as 'Transaction Month',
TRANSACTION_Table.AMOUNT
From
Transaction_Table
Where
Transaction_Table.Date_Of_Distribution between '7/1/2019' And '6/30/2021'
Thank you in advance!
The simplest way is to add 6 months and extract the year. In Standard SQL, this looks like:
extract(year from Date_Of_Distribution + interval '6 month')
Date/time functions are notoriously database dependent, so the exact syntax depends on the database you are using.
For instance, in SQL Server, it would be:
year(dateadd(month, 6, Date_Of_Distribution))

Update statement Syntax (PostgreSQL-Redshift)

In the time dimension we have added additional two columns called Fiscal Year and Fiscal Year Month which are to be populated. In our case Fiscal year starts from
Sep 01 and ends on Aug 31. (For example - Sep 01, 2017 to Aug 31,2018 is Fiscal Year 2018). I am trying to write an update statement in PostgreSQL.
(Logic - case when X.monthname in ('September','October','November','December') then (X.Year+1) else X.Year end)- But looks like I am not able to get the right syntax. Can you help build it ?
We have Date, Year, MonthName columns in our Time table which can be used in update statement.
Thanks.
I think the update would look like:
update x
set Year = Year + 1
where x.monthname in ('September', 'October', 'November', 'December') ;

SQL - check if an order date occurs after the second Saturday in July

I am querying against a table of 4 yrs of order transactions (pk = order number) and I'm looking to tag each record with particular date flags based on the order date - e.g., calendar year, calendar month, fiscal year, etc. There are date attributes that are specific to our business (e.g., not easily solved by a datepart function) that I'm having trouble with.
I was able to add "School Year" (for us that runs Aug 1 - July 31) using a case statement:
case
when datepart(month, oline.order_date_ready) between 8 and 12 then datepart(year, oline.order_date_ready)
else (datepart(year, oline.order_date_ready)-1)
end as school_yr
So for 1/19/2017, the above would return "2016", because to us the 2016 school year runs from Aug 1 2016 to July 31 2017.
But now I'm having trouble repeating the same kind of case statement for something called "Rollover Year". All of our order history tables are reset/"rolled over" on the 2nd Saturday in July every calendar year, so for example the most recent rollover date was Saturday July 9th 2016. Click to view - rollover year date ranges
My above case statement doesn't apply anymore because I can't just add "datepart(month, oline.order_date_ready) = 7" - I don't need the whole month of July, I just need all the orders occurring after the 2nd Saturday in that July. So in this example, I need everything occurring from Sat July 9 2016 to today to be flagged as rollover_date = 2016.
Is there a flexible way to do this without hard coding previous/future rollover dates into another table? That's the only way I can think to solve it currently, but I'm sure there must be a better way.
Thanks!
If you ask for the day-of-the-week of July 1st, then from there it's simple arithmetic, right? This query gives results matching your image:
SELECT y,
CONCAT(y, '-07-01')::timestamp +
CONCAT(6 - EXTRACT(DOW FROM CONCAT(y, '-07-01')::timestamp) + 7, ' days')::interval
FROM generate_series(2013, 2020) s(y)
ORDER BY y DESC
;
So given any date d from year y, if it comes before the 2nd Saturday of July, give it fiscal year y - 1. Otherwise give it fiscal year (school year?) y.

Get Year of Previous Month (For Jan 1st)

I'm currently building a YTD report in SSRS. I'm looking to edit the default "FROM" date in a calendar selection.
I'm looking to retrieve January 1st of the previous months year. For example:
(If it's Feb 16th, 2016 .. the result should be 1/1/2016
If it's Jan 10th, 2016 .. the result should be 1/1/2015)
I built this to retrieve the current year for jan 1st, but it causes issues if we're in January because I need it to retrieve the year of the previous month (in that case it would be 2015, not 2016).
Thanks!
Try this, it should work
=DateAdd(DateInterval.Month,-1,DateSerial(Year(Today), Month(Today), 1))
UPDATE:
Based on your comment I've created this expression. It is not tested but should work.
=IIF(Today.Month>1,
DateAdd(DateInterval.Month,-1,DateSerial(Year(Today), Month(Today), 1)),
DateAdd(DateInterval.Year,-1,DateSerial(Year(Today), Month(Today), 1))
)
Let me know if this helps.
select cast(cast(year(dateadd(mm, -1,getdate())) as varchar)+'-01-01' as date)
replace getdate() with which ever field you're basing this calculation on.
for testing:
select cast(cast(year(dateadd(mm, -1,'2015-01-22')) as varchar)+'-01-01' as date)
select cast(cast(year(dateadd(mm, -1,'2016-02-01')) as varchar)+'-01-01' as date)
select cast(cast(year(dateadd(mm, -1,'2015-12-12')) as varchar)+'-01-01' as date)
We want to use Date Serial which has the forma
=DateSerial(YYYY,MM,DD)
The Month is always January
The day is always the first
If the month is January, it's last year. Otherwise, it's this year.
So, assuming we have an SSRS report with a parameter called Date , we can create a new field for your January date as follows:
=iif(Month(Parameters!Date.Value)=1,
dateserial(Year(Parameters!Date.Value)-1,1,1),
dateserial(Year(Parameters!Date.Value),1,1))
if you want to do this in the query with T-SQL (version 2012) or later:
case when month(#DATE) = 1
then DATEFROMPARTS(YEAR(#DATE)-1,1,1)
else DATEFROMPARTS(YEAR(#DATE),1,1)
end
OR, in earlier versions
CASE WHEN MONTH(#DATE) = 1
THEN CAST(CAST((YEAR(#DATE)-1)*10000 + 101 AS CHAR(8)) AS DATE)
ELSE CAST(CAST((YEAR(#DATE)*10000+ 101) AS CHAR(8)) AS DATE)
END