我需要根据以前的记录返回 0 或 1。示例表:
DECLARE @x TABLE(ProductID INT, Failed bit, SampleDate date, LevelCode int);
INSERT @x VALUES
(101, 0, '20151201', 1),
(101, 1, '20151205', 2),
(101, 0, '20151206', 3),
(101, 1, '20151208', 2),
(102, 1, '20151202', 1),
(102, 0, '20151204', 2),
(102, 0, '20151205', 3),
(103, 0, '20160101', 1),
(103, 1, '20160102', 2),
(103, 0, '20160103', 2),
(104, 0, '20160101', 1),
(104, 0, '20160102', 2),
(104, 0, '20160103', 3);
最后一条记录我们唯一关心的是LevelCode(即每个ProductID的最后一条记录)。最后一条记录是否通过/失败无关紧要。然后,我们查看该 ProductID 的所有其他记录(因此最后一条记录之前的所有记录),如果失败,LevelCode 与最后一条记录相同,我们将 IsLastRunSameLevelAsPreviousRun 设置为 1,否则为 0:
ProductID IsLastRunSameLevelAsPreviousRun
101 1
102 0
103 1
104 0
如果 a 没有失败,ProductID
则IsLastRunSameLevelAsPreviousRun
应该返回 0。
非常感谢任何帮助或提示。
使用LAG ,您无需任何连接即可实现目标:
为每个组中的每一行
cte
获取相同的先前Failed
状态,当没有匹配的行时返回 0。它还计算每个组中的最后一个日期,以便稍后使用它来确定组中的最后一行。LevelCode
ProductID
这是它返回的内容:
主 SELECT 本质上只是使用
SampleDate = MaxSampleDate
过滤器获取每个组的最后一行,只提取ProductID
并将PrevFailed
后者重命名为IsLastRunSameLevelAsPreviousRun
,以便最终输出成为您想要的:一种方法是使用
ROW_NUMBER
两次。ProductID
首先对由( )分区的表的所有行进行编号,CTE_RowNumbersAll
并仅获取每个ProductID
(CTE_LastAll
) 的最后一行。然后对所有失败的行进行编号 (
CTE_RowNumbersFailed
) 并获取每个失败的最后一行ProductID
(CTE_LastFailed
)。最后将
LEFT JOIN
中间结果放在一起并用于CASE
比较LevelCode
值。更新
根据您的最后评论,我更改了查询。
CTE_RowNumbersFailed
现在基于CTE_RowNumbersAll
并且有一个额外的过滤器rnAll > 1
可以从考虑中删除最后一行。结果
希望这可以帮助