T-SQL CTE 自参考 CROSS APPLY 按日期有间隙的前一行
T-SQL CTE self-reference CROSS APPLY previous row by date with gaps
我在 SQL Server 2014 中有一个更新table table 的日期值序列(比如 dbo.sequence
)。日期是唯一的。
当有新的更新时,我想根据某些条件,例如如果来自 dbo.sequence
的先前值比当前 dbo.sequence
值 less/greater,它将被插入到 dbo.distributed_values
的指定列或在该列中变为 NULL。
主要思想如下:
;WITH
CTE_tbl (date, value, val_1, val_2, val_3)
AS (
SELECT ... FROM dbo.distributed_values -- get latest values from database
UNION ALL
SELECT
SEQ.date,
SEQ.value,
CASE
WHEN ABS (SEQ.value - prev.value) >= 0.5
THEN SEQ.value
ELSE NULL
END AS val_1,
...
FROM dbo.sequence AS SEQ
CROSS APPLY (SELECT * FROM CTE_tbl WHERE date = DATEADD(DAY, -1, SEQ.date)) AS prev
)
INSERT INTO dbo.distributed_values (...)
SELECT *
FROM CTE_tbl
ORDER BY date ASC
OPTION (MAXRECURSION 1000)
似乎大部分都有效,但 dbo.sequence
包含间隙,因此我无法使用 date = DATEADD(DAY, -1, SEQ.date)
之类的东西正确绑定到前一行。
2012-01-04
2012-01-05
2012-01-06
2012-01-09
2012-01-10
2012-01-11
如何在日期间隔的情况下正确绑定以前的值?
更新:
顺便说一下,我不能在 WHERE
子句中使用 LAG ... OVER
,我试过了。不知何故可以在这里使用吗?
添加另一个 CTE 并在递归 CTE 中使用它,如下所示:
;WITH
SequenceWithPrevious AS(
SELECT *
,PrevValue = LAG(value,1,NULL) OVER (ORDER BY SEQ.date)
,Prevdate = LAG(date,1,NULL) OVER (ORDER BY SEQ.date)
FROM dbo.sequence AS SEQ
),
CTE_tbl (date, value, val_1, val_2, val_3)
AS (
SELECT ... FROM dbo.distributed_values -- get latest values from database
UNION ALL
SELECT ...
FROM SequenceWithPrevious AS SEQ
CROSS APPLY (SELECT * FROM CTE_tbl WHERE date = SEQ.PrevDate) AS prev
)
INSERT INTO dbo.distributed_values (...)
SELECT *
FROM CTE_tbl
ORDER BY date ASC
OPTION (MAXRECURSION 1000)
我在 SQL Server 2014 中有一个更新table table 的日期值序列(比如 dbo.sequence
)。日期是唯一的。
当有新的更新时,我想根据某些条件,例如如果来自 dbo.sequence
的先前值比当前 dbo.sequence
值 less/greater,它将被插入到 dbo.distributed_values
的指定列或在该列中变为 NULL。
主要思想如下:
;WITH
CTE_tbl (date, value, val_1, val_2, val_3)
AS (
SELECT ... FROM dbo.distributed_values -- get latest values from database
UNION ALL
SELECT
SEQ.date,
SEQ.value,
CASE
WHEN ABS (SEQ.value - prev.value) >= 0.5
THEN SEQ.value
ELSE NULL
END AS val_1,
...
FROM dbo.sequence AS SEQ
CROSS APPLY (SELECT * FROM CTE_tbl WHERE date = DATEADD(DAY, -1, SEQ.date)) AS prev
)
INSERT INTO dbo.distributed_values (...)
SELECT *
FROM CTE_tbl
ORDER BY date ASC
OPTION (MAXRECURSION 1000)
似乎大部分都有效,但 dbo.sequence
包含间隙,因此我无法使用 date = DATEADD(DAY, -1, SEQ.date)
之类的东西正确绑定到前一行。
2012-01-04
2012-01-05
2012-01-06
2012-01-09
2012-01-10
2012-01-11
如何在日期间隔的情况下正确绑定以前的值?
更新:
顺便说一下,我不能在 WHERE
子句中使用 LAG ... OVER
,我试过了。不知何故可以在这里使用吗?
添加另一个 CTE 并在递归 CTE 中使用它,如下所示:
;WITH
SequenceWithPrevious AS(
SELECT *
,PrevValue = LAG(value,1,NULL) OVER (ORDER BY SEQ.date)
,Prevdate = LAG(date,1,NULL) OVER (ORDER BY SEQ.date)
FROM dbo.sequence AS SEQ
),
CTE_tbl (date, value, val_1, val_2, val_3)
AS (
SELECT ... FROM dbo.distributed_values -- get latest values from database
UNION ALL
SELECT ...
FROM SequenceWithPrevious AS SEQ
CROSS APPLY (SELECT * FROM CTE_tbl WHERE date = SEQ.PrevDate) AS prev
)
INSERT INTO dbo.distributed_values (...)
SELECT *
FROM CTE_tbl
ORDER BY date ASC
OPTION (MAXRECURSION 1000)