As stated above, I am looking to create a column in my dataset that says what percentage of a year is within a date range.
This was already being done in excel but I now have to reproduce this in SQL. Here are the column data types:
- Yr1 int
- Yr2 float
- Yr3 float
- Yr4 float
- Period Start datetime
- Period End datetime
- Period Indicator varchar
- Leap Year Indicator varchar
- Length of Period float
- Yr1 Earn % int
- Yr2 Earn % float
- Yr3 Earn % float
- Yr4 Earn % float
- Total Earn % float
Here is the SQL used to generate the columns. Yr1 Earn % unfortunately does not work. I receive an error saying: "Operand data type datetime is invalid for divide operator."
Is there any way to calculate this in SQL in the same fashion as below??
,[Yr1]+1 as 'Yr2'
,[Yr2]+1 as 'Yr3'
,[Yr3]+1 as 'Yr4'
,dateadd(d,[INSRD PERIOD START],'1899-12-30') as 'Period Start'
,dateadd(d,[INSRD PERIOD END],'1899-12-30') as 'Period End'
,CASE WHEN MONTH([PERIOD START]) = MONTH([PERIOD END]) AND DAY([PERIOD START]) = DAY([PERIOD END])
THEN 'Y'
ELSE 'N'
END AS 'Period Indicator'
,CASE WHEN ISDATE(CAST(YEAR([Period Start]) AS char(4)) + '0229') = 1
OR
ISDATE(CAST(YEAR([Period End]) AS char(4)) + '0229') = 1
THEN 'Y'
ELSE 'N'
END as 'Leap Year Indicator'
,(([Period End]-([Period Start]-CASE WHEN [Period Indicator]='Y'
THEN 0
ELSE 1
END)))/(CASE WHEN [Leap Year Indicator]='N'
THEN 365
ELSE 366
END) as 'Length of Period'
,(SELECT MAX(v)
FROM (VALUES (0),
(((SELECT MIN(w)
FROM (VALUES ('2019-06-30'),
(CASE WHEN [Period Indicator]='N'
THEN DATEADD(d,[Period End],'1899-12-30')
ELSE (DATEADD(DAY,-1,[Period End]))
END)
,
(DATEFROMPARTS([Yr1],'12','31'))
) as value(w))-
(SELECT MAX(x)
FROM (VALUES (DATEFROMPARTS([Yr1],'12','31')),
(DATEADD(DAY,-1,[Period Start]))
) as value(x)
)
)/((CASE WHEN [Period Indicator]='N'
THEN dateadd(DAY,[Period End],'1899-12-30')
ELSE DATEADD(DAY,-1,[Period End])
END)
- (DATEADD(DAY,-1,[Period Start]))))
) as value(v)
) as 'Yr1 Earn %'
,[Yr2 Earn %] as 'Yr2 Earn %'
,[Yr3 Earn %] as 'Yr3 Earn %'
,[Yr4 Earn %] as 'Yr4 Earn %'
,[Yr1 Earn %]+[Yr2 Earn %]+[Yr3 Earn %]+[Yr4 Earn %] as 'Total Earn %'
EDIT: Here is a copy of the excel formula used to generate the Yr1 Earn % column in the screenshot. z_eval='2019-06-30'
=MAX(0,(MIN(z_eval,IF($G2="N",$F2,$F2-1),DATE(A2,12,31))-MAX(DATE(A2->1,12,31),$E2-1))/(IF($G2="N",$F2,$F2-1)-($E2-1)))
EDIT: Thank you to everyone for your helpful comments so far. I converted all dates
to ints
with this block of code for Yr1 Earn %
. All values are defaulting to zero. Is the outer MAX(v)
function struggling to parse the inner Max/Min functions?
,(SELECT MAX(v) FROM (VALUES (0), (((SELECT MIN(w) FROM (VALUES (DATEDIFF(d,'1899-12-30','2019-06-30')), (CASE WHEN [Period Indicator]='N' THEN DATEDIFF(d,'1899-12-30',[Period End]) ELSE (DATEDIFF(d,'1899-12-30',DATEADD(DAY,-1,[Period End]))) END) , (DATEDIFF(d,'1899-12-30',DATEFROMPARTS([Yr1],'12','31'))) ) as value(w))- (SELECT MAX(x) FROM (VALUES (DATEDIFF(d,'1899-12-30',DATEFROMPARTS([Yr1],'12','31'))), (DATEDIFF(d,'1899-12-30',DATEADD(DAY,-1,[Period Start]))) ) as value(x) ) )/((CASE WHEN [Period Indicator]='N' THEN DATEDIFF(d,'1899-12-30',DATEADD(DAY,[Period End],'1899-12-30')) ELSE DATEDIFF(d,'1899-12-30',DATEADD(DAY,-1,[Period End])) END) - (DATEDIFF(d,'1899-12-30',DATEADD(DAY,-1,[Period Start]))))) ) as value(v) ) as 'Yr1 Earn %'