PFB剧本
CREATE TABLE LagLead
(
ID INT
,Flag TINYINT
,DateCreated DATETIME
)
GO
INSERT INTO LagLead
SELECT 100,0,'May 30 2000 11:37AM'
UNION ALL
SELECT 100,0,'May 30 2001 11:37AM'
UNION ALL
SELECT 100,0,'May 30 2002 11:37AM'
UNION ALL
SELECT 100,1,'May 30 2003 11:37AM'
UNION ALL
SELECT 100,1,'May 30 2004 11:37AM'
UNION ALL
SELECT 100,1,'May 30 2005 11:37AM'
UNION ALL
SELECT 100,0,'May 30 2006 11:37AM'
UNION ALL
SELECT 100,0,'May 30 2007 11:37AM'
UNION ALL
SELECT 100,0,'May 30 2008 11:37AM'
UNION ALL
SELECT 101,1,'May 30 2004 11:37AM'
UNION ALL
SELECT 101,1,'May 30 2005 11:37AM'
UNION ALL
SELECT 102,0,'May 30 2004 11:37AM'
来源表记录:
我需要输出类似下面查询的输出,但需要摆脱脚本中存在的硬编码2和9。感谢
预期产出:
我已尝试使用此脚本但需要将其设置为动态(删除硬编码2,9)
SELECT ID,Flag,Lag AS StartDate,Lead AS EndDate FROM
(
SELECT *
,CASE WHEN Flag != LEAD(Flag,1,9) OVER (PARTITION BY ID ORDER BY DateCreated) THEN 1 ELSE 0 END AS LeadFlag
,LAG(DateCreated,2,DateCreated) OVER (PARTITION BY ID ORDER BY DateCreated) AS Lag
,LEAD(DateCreated,1,DateCreated) OVER (PARTITION BY ID ORDER BY DateCreated) AS Lead
FROM LagLead
)src
WHERE LeadFlag = 1
使用滞后/导联功能并非强制性。
答案 0 :(得分:1)
我做到了没有滞后和领导。
with cte as (
select row_number() over (order by id, DateCreated) as r,
row_number() over (partition by id, flag order by id, DateCreated) as pr
, *
from LagLead
), grouped as (
select *, r - pr as g
from cte
)
select id, flag, min(DateCreated), max(DateCreated)
from grouped
group by id, flag, g
order by id, min(DateCreated)
你当然可以在一个cte中做到这一点,但我发现这种风格更具说明性。作为解释,我正在创建两个“虚拟”列 - 一个枚举整个集合,另一个枚举具有相同id和标志值的行集合中的行(两者都由同一组列排序)。关键的观察是,只要标志值不会在行之间发生变化,这两个列都会增加1,因此它们之间的差异在行之间是相同的。然而,一旦(id,flag)的组合改变,第一row_number和第二row_number将增加不同的值,因此两者之间的差异将与前一行不同。这有助于为我们提供便利的分组价值。顺便说一句,这类问题通常被称为“间隙和岛屿”。