Convert this datetime from SQL Server to Snowflake - date

I have this piece of code that works in SQL server. I'm having trouble getting it to run in snowflake. 'Datetime' is filetype DateTime in snowflake, but in SQL, it's just a date MM-DD-YYYY, so there is the 6:00 added to turn it into a datetime.
I want the end result to be a date.
Below is SQL Server:
CONVERT(DATE, TEMP.DATETIME - ISNULL((
SELECT CAST(MIN(s_first.FromTimeOfDay) AS DATETIME)
FROM Shift s_first
WHERE s_first.FromDay = s.FromDay
AND s_first.ShiftCalendarID = s.ShiftCalendarID
), CAST('6:00' AS DATETIME))) AS ProductionDate
Here is what I have in Snowflake:
to_date(TEMP.DATETIME) - ifnull(to_date((
SELECT MIN(s_first.FromTimeOfDay)
FROM Shift s_first
WHERE s_first.FromDay = s.FromDay
AND s_first.ShiftCalendarID = s.ShiftCalendarID
), (
SELECT to_date('1900-01-01 06:00:00.000')
))) AS ProductionDate
It's not liking the filetype. I get a filetype error:
invalid type [TO_DATE((SELECT MIN(S_FIRST.FROMTIMEOFDAY) AS "MIN(S_FIRST.FROMTIMEOFDAY)" FROM SHIFT AS S_FIRST WHERE (S_FIRST.FROMDAY = CORRELATION(S.FROMDAY)) AND (S_FIRST.SHIFTCALENDARID = CORRELATION(S.SHIFTCALENDARID))), (SELECT TO_DATE('1900-01-01 06:00:00.000') AS "TO_DATE('1900-01-01 06:00:00.000')" FROM (VALUES (null)) DUAL))] for parameter 'TO_DATE'
Update::
This is the original SQL that i'm trying to write in snowflake.
SELECT
e.Name AS ProductionUnit,
temp.DateTime AS DateTime,
s.Reference AS Shift,
CONVERT(TIME, temp.DateTime) AS Time,
CONVERT(DATE, temp.DateTime - ISNULL((SELECT CAST(MIN(s_first.FromTimeOfDay) AS DateTime) FROM Shift s_first WHERE s_first.FromDay = s.FromDay AND s_first.ShiftCalendarID = s.ShiftCalendarID), CAST('6:00' AS DateTime))) AS ProductionDate,
temp.ScrapReason AS ScrapReason,
temp.Quantity AS ScrapQuantity,
'Manually Registered' AS RegistrationType
FROM (SELECT
CAST(SUM(sreg.ScrapQuantity) AS int) AS Quantity,
sreas.Name As ScrapReason,
DATEADD(MINUTE, 30 * (DATEPART(MINUTE, sreg.ScrapTime) / 30), DATEADD(HOUR, DATEDIFF(HOUR, 0, sreg.ScrapTime), 0)) AS DateTime,
srer.EquipmentID AS EquipmentID
FROM qms.ScrapRegistration sreg WITH (NOLOCK)
INNER JOIN qms.ScrapReason sreas WITH (NOLOCK) ON sreas.ID = sreg.ScrapReasonID
INNER JOIN WorkRequest wr WITH (NOLOCK) ON wr.ID = sreg.WorkRequestID
INNER JOIN SegmentRequirementEquipmentRequirement srer WITH (NOLOCK) ON srer.SegmentRequirementID = wr.SegmentRequirementID
GROUP BY DATEADD(MINUTE, 30 * (DATEPART(MINUTE, sreg.ScrapTime) / 30), DATEADD(HOUR, DATEDIFF(HOUR, 0, sreg.ScrapTime), 0)), srer.EquipmentID, sreas.Name) temp
INNER JOIN Equipment e WITH (NOLOCK) ON e.ID = temp.EquipmentID
INNER JOIN ShiftCalendar sc WITH (NOLOCK) ON sc.ID = dbo.cfn_GetEquipmentShiftCalendarID(e.ID, temp.DateTime)
INNER JOIN Shift s WITH (NOLOCK) ON s.ID = dbo.cfn_GetShiftIDFromDateTime(temp.DateTime, sc.ID)
UNION
SELECT
e.Name AS ProductionUnit,
temp.DateTime AS DateTime,
s.Reference AS Shift,
CONVERT(TIME, temp.DateTime) AS Time,
CONVERT(DATE, temp.DateTime - ISNULL((SELECT CAST(MIN(s_first.FromTimeOfDay) AS DateTime) FROM Shift s_first WHERE s_first.FromDay = s.FromDay AND s_first.ShiftCalendarID = s.ShiftCalendarID), CAST('6:00' AS DateTime))) AS ProductionDate,
temp.ScrapReason AS ScrapReason,
temp.Quantity AS ScrapQuantity,
'Auto Registered' AS RegistrationType
FROM (SELECT
SUM(ISNULL(asr.ScrapQuantity, 0)) AS Quantity,
sreas.Name As ScrapReason,
DATEADD(MINUTE, 30 * (DATEPART(MINUTE, asr.ScrapTime) / 30), DATEADD(HOUR, DATEDIFF(HOUR, 0, asr.ScrapTime), 0)) AS DateTime,
srer.EquipmentID AS EquipmentID
FROM proj.AutoScrapRegistration asr WITH (NOLOCK)
INNER JOIN qms.ScrapReason sreas WITH (NOLOCK) ON sreas.ID = asr.ScrapReasonID
INNER JOIN WorkRequest wr WITH (NOLOCK) ON wr.ID = asr.WorkRequestID
INNER JOIN SegmentRequirementEquipmentRequirement srer WITH (NOLOCK) ON srer.SegmentRequirementID = wr.SegmentRequirementID
GROUP BY DATEADD(MINUTE, 30 * (DATEPART(MINUTE, asr.ScrapTime) / 30), DATEADD(HOUR, DATEDIFF(HOUR, 0, asr.ScrapTime), 0)), srer.EquipmentID, sreas.Name) temp
INNER JOIN Equipment e WITH (NOLOCK) ON e.ID = temp.EquipmentID
INNER JOIN ShiftCalendar sc WITH (NOLOCK) ON sc.ID = dbo.cfn_GetEquipmentShiftCalendarID(temp.EquipmentID, temp.DateTime)
INNER JOIN Shift s WITH (NOLOCK) ON s.ID = dbo.cfn_GetShiftIDFromDateTime(temp.DateTime, sc.ID)

So the first step is to make up some T-SQL data that to help understand hwo the old can ran.
So taking the inner most step on the original sql:
with Shift as (
select * from (values
(1, '2020-11-03', '06:30' )
) as t(ShiftCalendarID, fromday, FromTimeOfDay)
)
SELECT CAST(MIN(s_first.FromTimeOfDay) AS DATETIME) as sub
FROM Shift s_first;
we get:
sub
1900-01-01 06:30:00.000
so we can then weave temp and s together into this CTE data:
with Shift as (
select * from (
values
(1, '2020-11-03', '06:30' )
) as t(ShiftCalendarID, fromday, FromTimeOfDay)
), temp as (
select
t.ShiftCalendarID,
t.FromDay,
CAST(t.date_time AS DATETIME) as date_time
from (
values
(1, '2020-11-03', '2020-11-03 07:41:12' ),
(1, '2020-11-03', '2020-11-03 05:41:12' )
) as t(ShiftCalendarID, FromDay, date_time )
)
and run your existing sql:
select t.*
,CONVERT(DATE, t.date_time - ISNULL((
SELECT CAST(MIN(s_first.FromTimeOfDay) AS DATETIME)
FROM Shift s_first
WHERE s_first.FromDay = t.FromDay
AND s_first.ShiftCalendarID = t.ShiftCalendarID
), CAST('6:00' AS DATETIME))) AS ProductionDate
from temp as t;
which gives:
ShiftCalendarID
FromDay
date_time
ProductionDate
1
2020-11-03
2020-11-03 07:41:12.000
2020-11-03
1
2020-11-03
2020-11-03 05:41:12.000
2020-11-02
there is a subtraction of a time component from a datetime, if the min is not present a default of 6am is used.
And this code looks very much like it's a correlated subquery, so that will have it's own issues, but using the above fake data in snowflake:
so the data CTE's:
with Shift as (
select * from values
(1, '2020-11-03', '06:30' )
t(ShiftCalendarID, fromday, FromTimeOfDay)
), temp as (
select
t.ShiftCalendarID,
t.FromDay,
t.date_time::timestamp as date_time
from values
(1, '2020-11-03', '2020-11-03 07:41:12' ),
(1, '2020-11-03', '2020-11-03 05:41:12' ),
(2, '2020-11-03', '2020-11-03 05:41:12' )
t(ShiftCalendarID, FromDay, date_time )
)
and an extra help CTE to resolve the correlated subquery:
, min_times as (
select
ShiftCalendarID,
fromday,
MIN(FromTimeOfDay) as FromTimeOfDay
from Shift
group by 1,2
)
and then this expanded SQL to see all the steps:
select t.*
,nvl(mt.FromTimeOfDay::time, '06:00'::time) as sub_time
,dateadd('hour', -hour(sub_time), t.date_time) as da1
,dateadd('minute', -minute(sub_time), da1) as da2
,da2::date as ProductionDate
from temp as t
left join min_times as mt
on t.ShiftCalendarID = mt.ShiftCalendarID
and t.FromDay = mt.FromDay
gives:
SHIFTCALENDARID
FROMDAY
DATE_TIME
SUB_TIME
DA1
DA2
PRODUCTIONDATE
1
2020-11-03
2020-11-03 07:41:12.000
06:30:00
2020-11-03 01:41:12.000
2020-11-03 01:11:12.000
2020-11-03
1
2020-11-03
2020-11-03 05:41:12.000
06:30:00
2020-11-02 23:41:12.000
2020-11-02 23:11:12.000
2020-11-02
2
2020-11-03
2020-11-03 05:41:12.000
06:00:00
2020-11-02 23:41:12.000
2020-11-02 23:41:12.000
2020-11-02
so that can then be compacted (perhaps too far)..
select t.*
,dateadd('minute', -minute(nvl(mt.FromTimeOfDay::time, '06:00'::time)), dateadd('hour', -hour(nvl(mt.FromTimeOfDay::time, '06:00'::time)), t.date_time))::date as ProductionDate
from temp as t
left join min_times as mt
on t.ShiftCalendarID = mt.ShiftCalendarID
and t.FromDay = mt.FromDay
less compacted:
select ShiftCalendarID, FROMDAY, ProductionDate
from (
select t.ShiftCalendarID
,t.FROMDAY
,nvl(mt.FromTimeOfDay::time, '06:00'::time) as sub_time
,dateadd('hour', -hour(sub_time), t.date_time) as da1
,dateadd('minute', -minute(sub_time), da1) as da2
,da2::date as ProductionDate
from temp as t
left join min_times as mt
on t.ShiftCalendarID = mt.ShiftCalendarID
and t.FromDay = mt.FromDay
)
SHIFTCALENDARID
FROMDAY
PRODUCTIONDATE
1
2020-11-03
2020-11-03
1
2020-11-03
2020-11-02
2
2020-11-03
2020-11-02

Related

PostgreSQL pass value into INNER JOIN

PostgreSQL 11
How to pass o.create_date value into INNER JOIN? I need Max ID before o.create_date
SELECT o.id,
o.create_date date,
sum(oi.quantity) qty,
sum(oi.quantity * sp.price) total
FROM ax_order o
LEFT JOIN ax_order_invenotry oi on o.id = oi.order_id
LEFT JOIN ax_inventory i on i.id = oi.inventory_id
LEFT JOIN ax_suppliers s on s.id = o.supplier_id
INNER JOIN ax_supplier_price sp ON (sp.inventory_id = oi.inventory_id and sp.supplier_id = o.supplier_id)
INNER JOIN
(
SELECT inventory_id,
max(id) id
FROM ax_supplier_price
WHERE create_date <= o.create_date
GROUP BY inventory_id
) lsp ON (sp.id = lsp.id)
WHERE o.store_id = 13
AND o.supplier_id = 35
GROUP BY o.id, o.create_date
ORDER BY o.id
You could use the LATERAL join mechanism to make it work:
WITH ax_order AS (
SELECT *
FROM (VALUES (1, '2000-1-1'::date, 1, 1)) as x(id, create_date, store_id, supplier_id)
), ax_order_inventory AS (
SELECT *
FROM (VALUES (1, 2, 4)) as x(order_id, inventory_id, quantity)
), ax_supplier_price AS (
SELECT *
FROM (VALUES (1, 2, 1, 10, '1999-12-31'::date)) as x(id, inventory_id, supplier_id, price, create_date)
)
SELECT o.id,
o.create_date date,
sum(oi.quantity) qty,
sum(oi.quantity * sp.price) total
FROM ax_order o
LEFT JOIN ax_order_inventory oi on o.id = oi.order_id
INNER JOIN ax_supplier_price sp ON (sp.inventory_id = oi.inventory_id and sp.supplier_id = o.supplier_id)
INNER JOIN LATERAL
(
SELECT inventory_id,
max(lsp.id) id
FROM ax_supplier_price lsp
WHERE sp.create_date <= o.create_date
GROUP BY inventory_id
) lsp ON sp.id = lsp.id
GROUP BY o.id, o.create_date
ORDER BY o.id
I deleted some JOINs that were not strictly necessary and mocked your data as well as I could see. Note, however, that you could also use a WHERE clause to find it - which should be more efficient:
WITH ax_order AS (
SELECT *
FROM (VALUES (1, '2000-1-1'::date, 1, 1)) as x(id, create_date, store_id, supplier_id)
),
ax_order_inventory AS (
SELECT *
FROM (VALUES (1, 2, 4)) as x(order_id, inventory_id, quantity)
),
ax_supplier_price AS (
SELECT *
FROM (VALUES (1, 2, 1, 10, '1999-12-31'::date)) as x(id, inventory_id, supplier_id, price, create_date)
)
SELECT o.id,
o.create_date date,
sum(oi.quantity) qty,
sum(oi.quantity * sp.price) total
FROM ax_order o
LEFT JOIN ax_order_inventory oi on o.id = oi.order_id
INNER JOIN ax_supplier_price sp
ON (sp.inventory_id = oi.inventory_id and sp.supplier_id = o.supplier_id)
WHERE sp.id =
(
-- NOTE: no GROUP BY necessary!
SELECT max(lsp.id) id
FROM ax_supplier_price lsp
WHERE sp.create_date <= o.create_date
AND lsp.inventory_id = sp.inventory_id
)
GROUP BY o.id, o.create_date
ORDER BY o.id

How to PIVOT this query and display only TOP 10 records filtered by SUM(NetWrittenPremium) DESC

In this query I cant understand what would be the proper syntax to PIVOT it by month and also display just top 10 records based on SUM(NetWrittenPremium).
;with cte_TopClasses
AS (
select
b.YearNum,
b.MonthNum,
REPLACE(ClassCode,'+','') + ' - '+ QLL.Description as Description,
SUM( Premium) as NetWrittenPremium
FROM tblCalendar b
LEFT JOIN ProductionReportMetrics prm ON b.MonthNum=Month(prm.EffectiveDate) AND b.YearNum = YEAR(EffectiveDate)
AND prm.EffectiveDate >=DateAdd(yy, -1, DATEADD(d, 1, EOMONTH(GETDATE()))) AND prm.EffectiveDate <= EOMONTH(GETDATE()) AND CompanyLine = 'Ironshore Insurance Company'
LEFT JOIN NetRate_Quote_Insur_Quote Q ON prm.NetRate_QuoteID = Q.QuoteID
LEFT JOIN NetRate_Quote_Insur_Quote_Locat QL ON Q.QuoteID = QL.QuoteID
LEFT JOIN (SELECT * FROM NetRate_Quote_Insur_Quote_Locat_Liabi nqI
JOIN ( SELECT LocationID as LocID, MAX(ClassCode) as ClCode
FROM NetRate_Quote_Insur_Quote_Locat_Liabi GROUP BY LocationID ) nqA
ON nqA.LocID = nqI.LocationID AND nqA.ClCode = nqI.ClassCode ) QLL
ON QLL.LocationID = QL.LocationID
WHERE ( b.YearNum = YEAR(GETDATE())-1 and b.MonthNum >= MONTH(GETDATE())+1 ) OR
( b.YearNum = YEAR(GETDATE()) and b.MonthNum <= MONTH(GETDATE()) )
GROUP BY b.YearNum,b.MonthNum,ClassCode, QLL.Description
)
SELECT
--TOP 10
RANK() OVER (ORDER BY NetWrittenPremium DESC) AS Rank, *
FROM cte_TopClasses
WHERE Description IS NOT NULL
ORDER BY NetWrittenPremium DESC,YearNum,MonthNum
The result should look something like that:
If I use the query below and then using matrics in SSRS to PIVOT it - then after grouping by Description it only displays me 2 Description.
;with cte_TopClasses
AS (
select
b.YearNum,
b.MonthNum,
REPLACE(ClassCode,'+','') + ' - '+ QLL.Description as Description,
SUM( Premium) as NetWrittenPremium
FROM tblCalendar b
LEFT JOIN ProductionReportMetrics prm ON b.MonthNum=Month(prm.EffectiveDate) AND b.YearNum = YEAR(EffectiveDate)
AND prm.EffectiveDate >=DateAdd(yy, -1, DATEADD(d, 1, EOMONTH(GETDATE()))) AND prm.EffectiveDate <= EOMONTH(GETDATE()) AND CompanyLine = 'Ironshore Insurance Company'
LEFT JOIN NetRate_Quote_Insur_Quote Q ON prm.NetRate_QuoteID = Q.QuoteID
LEFT JOIN NetRate_Quote_Insur_Quote_Locat QL ON Q.QuoteID = QL.QuoteID
LEFT JOIN (SELECT * FROM NetRate_Quote_Insur_Quote_Locat_Liabi nqI
JOIN ( SELECT LocationID as LocID, MAX(ClassCode) as ClCode
FROM NetRate_Quote_Insur_Quote_Locat_Liabi GROUP BY LocationID ) nqA
ON nqA.LocID = nqI.LocationID AND nqA.ClCode = nqI.ClassCode ) QLL
ON QLL.LocationID = QL.LocationID
WHERE ( b.YearNum = YEAR(GETDATE())-1 and b.MonthNum >= MONTH(GETDATE())+1 ) OR
( b.YearNum = YEAR(GETDATE()) and b.MonthNum <= MONTH(GETDATE()) )
GROUP BY b.YearNum,b.MonthNum,ClassCode, QLL.Description
)
SELECT *
FROM (SELECT RANK() OVER (ORDER BY NetWrittenPremium DESC) AS Rank, *
FROM cte_TopClasses
WHERE Description IS NOT NULL) AA
WHERE AA.Rank <= 10
ORDER BY AA.NetWrittenPremium DESC, AA.YearNum, AA.MonthNum
And the result of it in SSRS matrics :
You could try something like this at the end of the query, rather than what is there now:
SELECT *
FROM (SELECT RANK() OVER (ORDER BY [Description] DESC) AS Rank, *
FROM cte_TopClasses
WHERE Description IN (SELECT [Description]
FROM (SELECT RANK() OVER (ORDER BY SUM(NetWrittenPremium) DESC) AS [Rank], [Description], SUM(NetWrittenPremium) AS total
FROM cte_TopClasses
WHERE [Description] IS NOT NULL
GROUP BY [Description]) BB
WHERE [Rank] <= 10)) AA
ORDER BY YearNum, MonthNum
This wraps the query in a SELECT, and filters the ranked results to the 10 you want.
Then use a matrix in the report to pivot the results.

Eliminate duplicate values on an inner join (is it even possible given this scenario?)

I have a query that pulls information from two different tables at a different granular level. I was wondering if it is even possible to keep the value from repeating on the right (only return one row with 110811.67 rest zero) and preserve all values on the left.
select x.pt_year,
x.pt_month,
x.pt_amount,
y.fp_earnedprem
from
(
select sum(a.amount) as pt_amount
, va.ACCT_YEAR as pt_year, va.ACCT_MONTHINYEAR as pt_month, ptp.PTRANS_CODE as pt_code
from fact_policytransaction a
join VDIM_ACCOUNTINGDATE va
on a.ACCOUNTINGDATE_ID=va.ACCOUNTINGDATE_ID
join DIM_POLICYTRANSACTIONTYPE ptp
on a.POLICYTRANSACTIONTYPE_ID=ptp.POLICYTRANSACTIONTYPE_ID
group by va.ACCT_YEAR, va.ACCT_MONTHINYEAR, ptp.PTRANS_CODE
) as x
join
(
select sum(fp.EARNED_PREM_AMT) as fp_earnedprem
, dm.MON_YEAR as fp_year, dm.MON_MONTHINYEAR as fp_month
from fact_policycoverage fp
join dim_month dm on fp.MONTH_ID=dm.MONTH_ID
group by dm.MON_YEAR, dm.MON_MONTHINYEAR
) as y
on x.pt_year = y.fp_year
and x.pt_month = y.fp_month
where x.pt_year=2016 and x.pt_month=6
order by x.pt_year, x.pt_month
pt_year pt_month pt_amount fp_earnedprem
2016 6 4340.00 110811.67
2016 6 15569.00 110811.67
2016 6 30024.00 110811.67
pt_year pt_month pt_amount fp_earnedprem
2016 6 4340.00 110811.67
2016 6 15569.00 0
2016 6 30024.00 0
you can use ROW_NUMBER
;with cte as (
select x.pt_year,
x.pt_month,
x.pt_amount,
y.fp_earnedprem
from
(
select sum(a.amount) as pt_amount
, va.ACCT_YEAR as pt_year, va.ACCT_MONTHINYEAR as pt_month, ptp.PTRANS_CODE as pt_code
from fact_policytransaction a
join VDIM_ACCOUNTINGDATE va
on a.ACCOUNTINGDATE_ID=va.ACCOUNTINGDATE_ID
join DIM_POLICYTRANSACTIONTYPE ptp
on a.POLICYTRANSACTIONTYPE_ID=ptp.POLICYTRANSACTIONTYPE_ID
group by va.ACCT_YEAR, va.ACCT_MONTHINYEAR, ptp.PTRANS_CODE
) as x
join
(
select sum(fp.EARNED_PREM_AMT) as fp_earnedprem
, dm.MON_YEAR as fp_year, dm.MON_MONTHINYEAR as fp_month
from fact_policycoverage fp
join dim_month dm on fp.MONTH_ID=dm.MONTH_ID
group by dm.MON_YEAR, dm.MON_MONTHINYEAR
) as y
on x.pt_year = y.fp_year
and x.pt_month = y.fp_month
where x.pt_year=2016 and x.pt_month=6
)
, Rn as (
select *
, ROW_NUMBER() over (partition by pt_year, pt_month order by pt_year, pt_month) as RoNum
from cte
)
select pt_year, pt_month, pt_amount
, IIF(RoNum = 1, fp_enarnedprem, 0)
from Rn
order by pt_year, pt_month
the main part is your own query, I only added below section and a line on top and moved order by to the bottom.
)
, Rn as (
select *
, ROW_NUMBER() over (partition by pt_year, pt_month order by pt_year, pt_month) as RoNum
from cte
)
select pt_year, pt_month, pt_amount
, IIF(RoNum = 1, fp_enarnedprem, 0)
from Rn
order by pt_year, pt_month

Cumulative time difference per group

I have a table structure like below
DECLARE #XTable TABLE
(
ColA Varchar(20),
ColB Varchar(20),
DateCol DATE
)
INSERT INTO #XTable
VALUES
('A', 'X1', '4/1/2015'), ('A', 'X2', '4/10/2015'), ('A', 'X3', '4/12/2015'),
('A', 'X4', '4/16/2015'), ('B', 'X1', '5/18/2015'), ('B', 'X2', '5/20/2015')
Expected output:
/*
ColA ColB DateCol Diff
A X1 4/1/2015 0
A X2 4/10/2015 9
A X3 4/12/2015 2
A X3 4/12/2015 11
A X4 4/16/2015 15
A X4 4/16/2015 5
A X4 4/16/2015 4
B X1 5/18/2015 0
B X2 5/20/2015 12
*/
for example:
A X4 will have a difference of date from A X1, A X2 and A X3
& A X3 will have a difference of date from A X1 & A X2
I am able to get difference from last row via below query
;WITH Dataf
AS (
SELECT
*,
ROW_NUMBER() OVER (ORDER BY ColA,ColB, DateCol) AS RowNum
FROM
#XTable
)
SELECT a.ColA, a.ColB, SUM(DATEDIFF(Dd,b.DateCol,a.DateCol)) as TotalTime
FROM
Dataf AS A
LEFT OUTER JOIN Dataf AS B
ON A.RowNum = B.RowNum + 1 and a.ColA = b.ColA
GROUP BY a.ColA, a.ColB
Thought of applying multiple CTE, here is on what I am working now
;WITH Dataf
AS (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY ColA ORDER BY DateCol) AS RowNum
FROM
#XTable
),
CTE AS
(
SELECT ColA, ColB, DateCol, RowNum, NULL AS DateDifference
FROM Dataf WHERE RowNum = 1
UNION ALL
SELECT DF.ColA, DF.ColB, DF.DateCol, DF.RowNum ,
DATEDIFF(DD, CT.DateCol, DF.DateCol) AS DateDifference
FROM Dataf DF
JOIN CTE CT ON DF.ColA = CT.ColA AND DF.RowNum = CT.RowNum + 1
)
SELECT *
FROM CTE
ORDER BY ColA
You can instead use LEFT OUTER JOIN to the CTE you prepared. Here is how it can be done
;WITH DataForm
AS (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY Cola ORDER BY DateCol) AS RowNum
FROM
#XTable
)
SELECT ColA, ColB, DateCol, 0
FROM DataForm WHERE RowNum = 1
UNION
SELECT T1.ColA, T1.ColB, T1.DateCol
, DATEDIFF(dd,T2.DateCol, T1.Datecol)
FROM DataForm T1
LEFT OUTER JOIN DataForm T2 ON T1.ColA = T2.ColA
AND T1.RowNum >= T2.RowNum
WHERE DATEDIFF(dd,T2.DateCol, T1.Datecol) > 0
SQL Fiddler Example

tsql distinct count subquery2

I am using SSMS 2008 and I need to use a subquery to return the count of unique records / client. How do I do this? Currently I am getting the error:
Msg 512, Level 16, State 1, Line 58
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or
Here is my pseudocode currently:
SELECT A.Program, A.PEOPLE_ID, K.EVENT_NAME, A.Program2, A.Program3
(SELECT COUNT(DISTINCT K.EVENT_NAME)
FROM #TEMP1 A, evolv_cs.dbo.facility_view F, evolv_cs.dbo.people_x N, event_view K WITH (NOLOCK)
WHERE F.group_profile_id = A.group_profile_id AND
K.event_definition_id = a.event_definition_id AND
A.people_id = N.people_id
GROUP BY K.EVENT_NAME) as DistinctEvent
FROM #TEMP1 A
JOIN event_view K WITH (NOLOCK) on K.event_definition_id = A.event_definition_id
WHERE #START_DATE BETWEEN A.Enrolled_Date AND DATEADD(D, 14, A.Enrolled_Date)
AND (#SERVICE IS NULL OR #SERVICE = K.event_name)
GROUP BY
A.Program, A.PEOPLE_ID, K.EVENT_NAME, A.Program2, A.Program3
This should work and run more efficiently.
SELECT A.Program, A.PEOPLE_ID, sub.EVENT_NAME, A.Program2, A.Program3, sub.DistinctEvent
FROM (
SELECT K.EVENT_NAME, COUNT(DISTINCT K.EVENT_NAME) as DistinctEvent
FROM #TEMP1 as A
JOIN evolv_cs.dbo.facility_view as F ON F.group_profile_id = A.group_profile_id
JOIN evolv_cs.dbo.people_x as N ON A.people_id = N.people_id
JOIN event_view as K WITH (NOLOCK) ON K.event_definition_id = a.event_definition_id
WHERE #START_DATE BETWEEN A.Enrolled_Date AND DATEADD(D, 14, A.Enrolled_Date)
AND (#SERVICE IS NULL OR #SERVICE = K.event_name)
GROUP BY K.EVENT_NAME
) as sub
JOIN #TEMP1 as A ON A.EVENT_NAME = sub.EVENT_NAME