使用重复属性将 Table 拆分为 Windows
Split Table into Windows with Recurring Attributes
我的标题很糟糕,因为我不确定如何描述挑战。如果有人能想到一个更具描述性的标题,我会喜欢编辑。希望我的 input/desired 输出将有助于解释。这是一些示例输入数据:
create table #input (
num varchar(10),
code varchar(10),
event_date date
)
insert into #input (num, code, event_date)
values('123456', 'Active', '2007-09-10'),
('123456', 'Active', '2010-09-15'),
('123456', 'Active', '2010-09-24'),
('123456', 'Inactive', '2018-09-17'),
('123456', 'Inactive', '2019-01-01'),
('123456', 'Active', '2019-02-08')
select *
from #input
order by event_date
我想用相同的数字标记每组 num + code 的每条记录。但是,我希望时间段保持分开。这是期望的结果:
create table #result (
num varchar(10),
code varchar(10),
event_date date,
tag int
)
insert into #result (num, code, event_date, tag)
values('123456', 'Active', '2007-09-10', 1),
('123456', 'Active', '2010-09-15', 1),
('123456', 'Active', '2010-09-24', 1),
('123456', 'Inactive', '2018-09-17', 2),
('123456', 'Inactive', '2019-01-01', 2),
('123456', 'Active', '2019-02-08', 3)
select *
from #result
order by event_date
显然正常 window 这样的分区...
select *, row_number() over(partition by num, code order by event_date) rn
from #input
order by event_date
...行不通,因为没有要划分两个 "Active" 组的字段(两个组,因为它们发生在两个时间范围内)。我将如何达到我想要的结果?我有一种预感,一系列 lag()
和 lead()
函数可能会起作用,但我找不到任何有意义的地方。
或者,我将如何获得结果以使类别重叠一个?
create table #result_new (
num varchar(10),
code varchar(10),
event_date date,
tag int
)
insert into #result (num, code, event_date, tag)
values('123456', 'Active', '2007-09-10', 1),
('123456', 'Active', '2010-09-15', 1),
('123456', 'Active', '2010-09-24', 1),
('123456', 'Inactive', '2018-09-17', 1),
('123456', 'Inactive', '2019-01-01', 2),
('123456', 'Active', '2019-02-08', 2)
select *
from #result_new
order by event_date
LAG
完成了一半,但不是全部。您可以使用 LAG
检查最后一行的值,并创建(我所说的)开关。然后,您可以使用 SUM
window 函数和 ROWs BETWEEN
子句来获取 tag
:
的值
WITH CTE AS(
SELECT num,
code,
event_date,
CASE WHEN code = LAG(code) OVER (PARTITION BY num ORDER BY event_date) THEN 0 ELSE 1 END AS Switch
FROM #input)
SELECT num,
code,
event_date,
SUM(Switch) OVER (PARTITION BY num ORDER BY event_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS tag
FROM CTE;
我的标题很糟糕,因为我不确定如何描述挑战。如果有人能想到一个更具描述性的标题,我会喜欢编辑。希望我的 input/desired 输出将有助于解释。这是一些示例输入数据:
create table #input (
num varchar(10),
code varchar(10),
event_date date
)
insert into #input (num, code, event_date)
values('123456', 'Active', '2007-09-10'),
('123456', 'Active', '2010-09-15'),
('123456', 'Active', '2010-09-24'),
('123456', 'Inactive', '2018-09-17'),
('123456', 'Inactive', '2019-01-01'),
('123456', 'Active', '2019-02-08')
select *
from #input
order by event_date
我想用相同的数字标记每组 num + code 的每条记录。但是,我希望时间段保持分开。这是期望的结果:
create table #result (
num varchar(10),
code varchar(10),
event_date date,
tag int
)
insert into #result (num, code, event_date, tag)
values('123456', 'Active', '2007-09-10', 1),
('123456', 'Active', '2010-09-15', 1),
('123456', 'Active', '2010-09-24', 1),
('123456', 'Inactive', '2018-09-17', 2),
('123456', 'Inactive', '2019-01-01', 2),
('123456', 'Active', '2019-02-08', 3)
select *
from #result
order by event_date
显然正常 window 这样的分区...
select *, row_number() over(partition by num, code order by event_date) rn
from #input
order by event_date
...行不通,因为没有要划分两个 "Active" 组的字段(两个组,因为它们发生在两个时间范围内)。我将如何达到我想要的结果?我有一种预感,一系列 lag()
和 lead()
函数可能会起作用,但我找不到任何有意义的地方。
或者,我将如何获得结果以使类别重叠一个?
create table #result_new (
num varchar(10),
code varchar(10),
event_date date,
tag int
)
insert into #result (num, code, event_date, tag)
values('123456', 'Active', '2007-09-10', 1),
('123456', 'Active', '2010-09-15', 1),
('123456', 'Active', '2010-09-24', 1),
('123456', 'Inactive', '2018-09-17', 1),
('123456', 'Inactive', '2019-01-01', 2),
('123456', 'Active', '2019-02-08', 2)
select *
from #result_new
order by event_date
LAG
完成了一半,但不是全部。您可以使用 LAG
检查最后一行的值,并创建(我所说的)开关。然后,您可以使用 SUM
window 函数和 ROWs BETWEEN
子句来获取 tag
:
WITH CTE AS(
SELECT num,
code,
event_date,
CASE WHEN code = LAG(code) OVER (PARTITION BY num ORDER BY event_date) THEN 0 ELSE 1 END AS Switch
FROM #input)
SELECT num,
code,
event_date,
SUM(Switch) OVER (PARTITION BY num ORDER BY event_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS tag
FROM CTE;