SQL to separate YYYY MM to fiscal year - sql

I have a column which states month and year YYYY MM. I've separated those into two columns (Year and Month). The problem is, the year is the calendar year whereas ideally I need the fiscal year I use (Apr 01 to Mar 31 - This will never change).
Other solutions I've seen are based on date format, whereas my original column is string.
I need a statement that returns the fiscal year for my new year column instead of the calendar year.
My current statement is:
Select Month,
parsename(replace(Month,' ','.'),1) as MonthM,
parsename(replace(Month,' ','.'),2) as Year
FROM TblTrade
Which works to separate the columns.
So expected results would be for example:
Feb 15 becomes Feb and 2015.
Apr 15 becomes Apr and 2016.
Please advise.

Sql server:
declare #date datetime = getdate();
select
(YEAR(DATEADD(Month,-((DATEPART(Month,#date)+5) %12),#date))) AS Financial_Year
Assuming April is month 1

Try this
select case
when to_char(to_date(column_name,'yyyy mm'),'mm') between 01 and 03
then to_char(trunc(to_date(column_name,'yyyy mm')),'yyyy')-1
else to_number(to_char(trunc(to_date(column_name,'yyyy mm')),'yyyy')) end
fiscal_year
from table_name
I'm using oracle db
This will work when column is string and has valid data i.e date in format like yyyy mm

Since you've read those other articles (you should really mention what research you've done in your question) and you're still having problems, I've had a play for you.
If I understand correctly, you have a varchar with YYYY MM eg
2015 01
2015 02
2015 03
2015 04
etc And you want
Jan 2014
Feb 2014
Mar 2014
Apr 2015
Here goes...
Setup some test data
DROP TABLE IF EXISTS #Test;
WITH Dates AS (
SELECT CAST(GETDATE() AS DATE) AS Date
UNION ALL
SELECT DATEADD(MONTH, -1, Date) FROM Dates
WHERE Date > '20140101'
)
SELECT DISTINCT
CONVERT(VARCHAR(4), YEAR(Date)) + ' ' +RIGHT(CONVERT(VARCHAR(6), Date, 112), 2) YearMonth
INTO #Test
FROM Dates
OPTION (MAXRECURSION 0);
SELECT * FROM #Test
YearMonth
---------
2013 12
2014 01
2014 02
2014 03
2014 04
2014 05
etc
Find Fiscal Year
SELECT
LEFT(YEARMONTH, 4) Year
,RIGHT(YEARMONTH, 2) Month
,LEFT(DATENAME(MONTH , DateAdd( month , CONVERT(INT,RIGHT(YEARMONTH, 2)) , -1 )), 3) MonthName
,IIF(CONVERT(INT, RIGHT(YEARMONTH, 2)) >= 4, CONVERT(INT,LEFT(YEARMONTH, 4)), CONVERT(INT,LEFT(YEARMONTH, 4)-1 )) FiscalYear
FROM #TEST
Year Month MonthName FiscalYear
---- ----- --------- -----------
2013 12 Dec 2013
2014 01 Jan 2013
2014 02 Feb 2013
2014 03 Mar 2013
2014 04 Apr 2014
2014 05 May 2014
2014 06 Jun 2014
etc
You could put the year/month parsing in a sub query just to make the code cleaner and some of the nasty formatting could be replaced with FORMAT since you're on 2012.
Hope this is what you're after and helps.

Since you included the Tableau tag, I'll describe the Tableau approach -- which is a little different than the other answers since you tend to specify what you want to Tableau, and let its driver generate the necessary SQL for your database.
First, it will work best if you have a single field that has datatype DATE instead of separate fields for month and year.
You can then roll up dates to the nearest year, month, day etc (actually truncating to the beginning of the period) or extract specific parts of dates year, month, day etc as needed for grouping/display.
The added benefit of working with a true DATE datatype is that you can tell Tableau the beginning of your fiscal year for each data source, and it will sort dates appropriately. Just right click on a data source and set the date properties. You can also set the start of the week and the date format.

Related

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') ;

T-SQL: August is the beginning of next years financial year, code to dynamically to change the batch ids

I have a column called batch_id with a list of dates - 2016080184 ie date 2016 08 01 84(84, I believe a time part).
I need to update the batch_id (varchar(25)) to change to 2017010184, based on another column voucher_date (datetime) = 2016-08-01 00:00:00.000
So if the voucher date was 2016-08-02 00:00:00.000, then the batch_id needs to change from 2016080278 to 2017010278 (78 at the end here doesn't matter)
August is the first month for the financial year, so August would effectively become January, September would become February etc.. and the year from Aug needs to indicate the following year ie this year is 2016 therefore batch_id should start with 2017.
Next August batch_id should indicate 2018 etc..
The file I receive is always a day behind to make things more complicated.
I am a little confused about your requirement for the year to change, but this should give you all you need to get started:
declare #BatchID nvarchar(10) = '2016080184'
select convert(nvarchar(8),dateadd(month,-7,cast(left(#BatchID,8) as date)),112) + right(#BatchID,2) as NewBatchID_SameYear
,convert(nvarchar(8),dateadd(month,5,cast(left(#BatchID,8) as date)),112) + right(#BatchID,2) as NewBatchID_NextYear
You can apply the above date changes with a CASE statement on the voucher_date column as required.

Get the latest date in SQL from text format

I'm trying to get the latest date from a csv file , the dates are stored in this form
NOV 14 2010
FEB 1 2012
JUN 18 2014
and my query is like
SELECT Max(date) from table
I'm getting
NOV 14 2010
any idea ?
They are likely being considered strings(varchar) not DateTimes. Try:
SELECT MAX(CAST(TABLE.date as DateTime)) FROM TABLE

Objective: Create Staff Turnover Report from scratch

I have a requirement to create staff turnover report that should display following information according to parameterized period:
current staff
starters
leavers
manager
contracted site
Currently, I have a few ideas how to get a report. Either create slowly changing dimension or copy snapshots of employees table for each period or track starter and leavers seperately for each payrun. I have tried slowly changing dimension and it did fine job on new starters; however, it failed on leavers. I am not sure if tracking starters and leaver for each payruns would work.
Created a table below as a start of solution
I am relatively new in MS SQL 2008 business. Please adise. The main goal is to identify managers and contracted sites with highest staff turnover.
Notes
-Currently, I am not using any specific techonlogy and looking for solution.
-I do intend to build and design a brand new database for the sake of the report. By database I mean a few collection of tables that sit on CRM database (SQL 2008). By Collection of tables I mean "dimension" table for managers, "dimension" table of contracted sites, and a table of staff. So currently, I think that my solution should have at least 3 tables; however, my skills are not that good to solve the puzzle.
I think that have tables above would let me to write a SQL query that could compare different periods and get required results.
payno depcod Idd Imported
12568 EDE322001 12568EDE322001A 31 December 2011
12568 EDE322001 12568EDE322001B 31 December 2011
16822 EDE322001 16822EDE322001A 31 December 2011
17694 EDE322001 17694EDE322001A 31 December 2011
12568 EDE322001 12568EDE322001A 04 January 2012
12568 EDE322001 12568EDE322001B 04 January 2012
16822 EDE322001 16822EDE322001A 04 January 2012
17694 EDE322001 17694EDE322001A 04 January 2012
12568 EDE322001 12568EDE322001A 31 January 2012
12568 EDE322001 12568EDE322001B 31 January 2012
16822 EDE322001 16822EDE322001A 31 January 2012
17694 EDE322001 17694EDE322001A 31 January 2012
17661 EDE322001 17661EDE322001A 31 January 2012
12568 EDE322001 12568EDE322001A 01 February 2012
12568 EDE322001 12568EDE322001B 01 February 2012
16822 EDE322001 16822EDE322001A 01 February 2012
17906 EDE322001 17906EDE322001A 01 February 2012
17907 EDE322001 17907EDE322001A 01 February 2012
12568 EDE322001 12568EDE322001A 29 February 2012
12568 EDE322001 12568EDE322001B 29 February 2012
17907 EDE322001 17907EDE322001A 29 February 2012
Table above is table of snapshots. Snapshot date is displayed in Imported Column. ( Applogoes for messy table; I could not figure out how to make a table) Now i need to find a away how to compare one date to another (ideally in the loop) to figure out the difference between 1st date and following date.
For instance, 17661 EDE322001 17661EDE322001A 31 January 2012 is a new staff and 16822 EDE322001 16822EDE322001A 01 February 2012 is a leaver.
Many thanks
I may be looking at this too simplistically given all the talk about slowly changing dimensions, etc, but what's wrong with a plain old bit of SQL? I'm going to assume you have an Employee table with Manager, ContractedSite, StartDate and EndDate fields.
You want the following:
Current staff. Is this current at the start of the period or at the end of the period or active at some time during the period?
Starters. People who have a StartDate greater than or equal to the start of the period but less than or equal to the end of the period.
Leavers. People who have an EndDate greater than or equal to the start of the period but less than or equal to the end of the period.
Turnover. Which brings us back to what you mean by "Current staff". Turnover is essentially the difference between the current staff at the start of the period and the current staff at the end of the period, expressed either as a raw number or a percentage. So current staff at the start of the period are people with a StartDate less than the period start and either no EndDate or an EndDate greater than or equal to the start of the period. Similarly with the current staff at the end of the period.
So you have some specific cases to extract from your data:
SELECT Manager, ContractedSite,
SUM(CASE WHEN StartDate < #PeriodStart AND ((EndDate IS NULL) OR (EndDate >= #PeriodStart)) THEN 1 END) AS OpeningStaff,
SUM(CASE WHEN StartDate >= #PeriodStart AND StartDate <= #PeriodEnd THEN 1 END) AS Starters,
SUM(CASE WHEN EndDate >= #PeriodStart AND EndDate <= #PeriodEnd) THEN 1 END) AS Leavers,
SUM(CASE WHEN StartDate <= #PeriodEnd AND ((EndDate IS NULL) OR (EndDate > #PeriodEnd)) THEN 1 END) AS ClosingStaff
FROM Employee
WHERE (StartDate <= #PeriodEnd) AND ((EndDate IS NULL) OR (EndDate >= #PeriodStart))
GROUP BY Manager, ContractedSite
ORDER BY Manager, ContractedSite
Now you just need to calculate the difference between OpeningStaff and ClosingStaff in your report to get the turnover and you're done.

Multiple conditions within WHERE clause

This query is working fine:
SELECT * FROM tablename where Date >'20091109' and id='11';
But below this query does not return anything.
SELECT * FROM tablename
WHERE Date BETWEEN ('20091109' AND '20081010') AND id='11';
between ('20091109' and '20081010')
This is anything after 9th Nov 2008 and before 10th Oct 2008. Of course if show nothing.
Do you mean this which is 10 Oct 2008 to 8th Nov 2009 inclusive
Date >= '20081010' AND Date < '20091109'
or this which is 10 Oct 2008 to 9th Nov 2009 inclusive
Date >= '20081010' AND Date < '20091110'
Edit: Removed SQL Server references
SELECT * FROM
tablename
where Date between '20081010' and '20091109'
and id='11';