sql - 如何在值更改后创建新的顺序标志(在 SQL 中)
问题描述
我正在尝试在更改部分时创建一个顺序数字标志。
当学生加入某个部分时,该标志应为 1,并继续为 1,直到部分发生变化。第一次更改的标志应为 2,第二次更改应为 3,依此类推。
由于一个部分可以在更改后重复,我发现创建期望的结果具有挑战性。
任何帮助将不胜感激。
样本数据
create table dbo.cluster_test
(student_id int not null
,record_date date not null
,section varchar(30) null)
insert into cluster_test
(student_id, record_date, section)
values
(123, '2020-02-06', NULL)
,(123, '2020-05-14', 'A')
,(123, '2020-08-12', 'A')
,(123, '2020-09-01', 'B')
,(123, '2020-09-15', 'A')
,(123, '2020-09-29', 'A')
,(123, '2020-11-02', NULL)
,(123, '2020-11-30', NULL)
,(789, '2020-01-12', NULL)
,(789, '2020-04-12', 'A')
,(789, '2020-05-03', NULL)
,(789, '2020-06-13', 'A')
,(789, '2020-06-30', 'B')
,(789, '2020-07-01', 'B')
,(789, '2020-07-22', 'A')
期望的结果
学生卡 | 记录日期 | 部分 | 旗帜 |
---|---|---|---|
123 | 2020-02-06 | 空值 | 空值 |
123 | 2020-05-14 | 一种 | 1 |
123 | 2020-08-12 | 一种 | 1 |
123 | 2020-09-01 | 乙 | 2 |
123 | 2020-09-15 | 一种 | 3 |
123 | 2020-09-29 | 一种 | 3 |
123 | 2020-11-02 | 空值 | 空值 |
123 | 2020-11-30 | 空值 | 空值 |
789 | 2020-01-12 | 空值 | 空值 |
789 | 2020-04-12 | 一种 | 1 |
789 | 2020-05-03 | 空值 | 空值 |
789 | 2020-06-13 | 一种 | 2 |
789 | 2020-06-30 | 乙 | 3 |
789 | 2020-07-01 | 乙 | 3 |
789 | 2020-07-22 | 一种 | 4 |
试图:
select
student_id
,record_date
,section
,case when section is not null then row_number() over(partition by student_id, section order by record_date asc)
end row#
,case when (section is not null) and (lag(section, 1) over(partition by student_id order by record_date asc) is null) then 'start'
when (lag(section, 1) over(partition by student_id order by record_date asc) is not null) and (section != lag(section, 1) over(partition by student_id order by record_date asc)) then 'change'
end chk_txt
,case when section is not null then (case when (section is not null) and (lag(section, 1) over(partition by student_id order by record_date asc) is null) then 1
when (lag(section, 1) over(partition by student_id order by record_date asc) is not null) and (section != lag(section, 1) over(partition by student_id order by record_date asc)) then 1
else 0
end)
end chk_val2
from cluster_test
order by 1, 2
解决方案
这是差距和孤岛问题。您可以使用如下分析函数:
Select student_id, record_date, section,
Case when section is not null
Then sum(case when section is not null and (section <> lgs or lgs is null) then 1 end)
over (partition by student_id order by record_date)
End as flag
From (
Select student_id, record_date, section,
Lag(section) over (partition by student_id order by record_date) as lgs
From cluster_test t
) t
order by student_id, record_date;
推荐阅读
- c# - 从外部程序集获取所有引用程序集的路径
- rest - 如何更新(检索/修改/发布)wiki 内容
- angular - CSS3动画在Angular组件中不起作用
- bash - 尽管有源 bashrc,但无法在 shell 脚本上运行别名命令
- visual-studio-code - 将字符串文件路径转换为 vscode.Uri
- python - 更快的 collections.Counter - 类似 pandas Series 的操作
- c# - C#中使用Linq根据字典对象查询数据
- python-3.x - 具有其他多列条件的列上的空单元格将使用另一列中的日期加上 dateoffset(7) 进行更新
- r - 如何绘制具有多个参数的函数
- typescript - 用于函数回调的打字稿键入可与函数声明一起使用