Sql 密集秩,由A列划分,按B列的变化递增,但按C列排序
我有一张这样的桌子Sql 密集秩,由A列划分,按B列的变化递增,但按C列排序,sql,sql-server,ssms,gaps-and-islands,Sql,Sql Server,Ssms,Gaps And Islands,我有一张这样的桌子 name|subtitle|date ABC|excel|2018-07-07 ABC|excel|2018-08-08 ABC|ppt|2018-09-09 ABC|ppt|2018-10-10 ABC|excel|2018-11-11 ABC|ppt|2018-12-12 DEF|ppt|2018-12-31 我想添加一列,每当字幕发生变化时,该列都会递增,如下所示: name|subtitle|date|Group_Number ABC|excel|2018-07-0
name|subtitle|date
ABC|excel|2018-07-07
ABC|excel|2018-08-08
ABC|ppt|2018-09-09
ABC|ppt|2018-10-10
ABC|excel|2018-11-11
ABC|ppt|2018-12-12
DEF|ppt|2018-12-31
我想添加一列,每当字幕发生变化时,该列都会递增,如下所示:
name|subtitle|date|Group_Number
ABC|excel|2018-07-07|1
ABC|excel|2018-08-08|1
ABC|ppt|2018-09-09|2
ABC|ppt|2018-10-10|2
ABC|excel|2018-11-11|3
ABC|ppt|2018-12-12|4
DEF|ppt|2018-12-31|1
问题是,如果我对(按名称顺序按副标题划分)执行稠密的_rank(),那么该组不仅会将所有副标题划分为一个组,而且还会删除日期顺序。我也尝试过使用lag函数,但当您试图增加列时,这似乎不是很有用
有没有一个简单的方法来实现这一点
请记住,我使用的表格有数百个不同的名称。快速回答
declare @table table (name varchar(20),subtitle varchar(20),[date] date )
insert into @table (name,subtitle,date)
values
('ABC','excel','2018-07-07'),
('ABC','excel','2018-08-08'),
('ABC','ppt','2018-09-09'),
('ABC','ppt','2018-10-10'),
('ABC','excel','2018-11-11'),
('ABC','ppt','2018-12-12'),
('DEF','ppt','2018-12-31');
with nums as (
select *,
case when subtitle != lag(subtitle,1) over (partition by name order by date)
then 1
else 0 end as num
from @table
)
select *,
1+sum(num) over (partition by name order by date) AS Group_Number
from nums
解释
你问的不是确切的排名。您正试图在严格按日期排序的序列中找到名称和副标题相同的位置
为此,可以将当前行的值与前一行的值进行比较。如果他们匹配,你在同一个“岛”。如果不是,就有一个开关。每次检测到更改时,您都可以使用它发出eg1
这就是:
CASE WHEN subtitle != LAG(subtitle,1) OVER (PARTITION BY name ORDER BY date)
THEN 1
一旦获得该值,您就可以使用运行总数计算更改的数量:
sum(num) over (partition by name order by date) AS Group_Number
这将生成从0开始的值。要获得从1开始的数字,只需添加1:
1+sum(num) over (partition by name order by date) AS Group_Number
更新
正如T.克劳森在评论中所解释的那样,逆转比较将摆脱+1
:
with nums as (
select *,
case when subtitle = lag(subtitle,1) over (partition by name order by date)
then 0
else 1 end as num
from @table
)
select *,
sum(num) over (partition by name order by date) AS Group_Number
from nums
这也是一种更好的检测孤岛的方法,即使这种情况下的结果是相同的。第一个查询将生成以下结果:
name subtitle date num Group_Number
ABC excel 2018-07-07 0 1
ABC excel 2018-08-08 0 1
ABC ppt 2018-09-09 1 2
ABC ppt 2018-10-10 0 2
ABC excel 2018-11-11 1 3
ABC ppt 2018-12-12 1 4
DEF ppt 2018-12-31 0 1
当检测到除边界外的字幕中断时,查询将发出1
第二个查询返回:
name subtitle date num Group_Number
ABC excel 2018-07-07 1 1
ABC excel 2018-08-08 0 1
ABC ppt 2018-09-09 1 2
ABC ppt 2018-10-10 0 2
ABC excel 2018-11-11 1 3
ABC ppt 2018-12-12 1 4
DEF ppt 2018-12-31 1 1
在这种情况下,每次更改都会发出
1
,包括边界没有日期排序,除非您使用ORDER BY
子句指定日期排序。您尝试了什么,期望了什么,得到了什么?您首先需要执行“孤岛和间隙”以确定每个行(例如excel
行)所属的行组,然后您可以按名称和孤岛进行分区。您可以使用subtitle=而不是!=然后倒过来,不要在末尾加1(并使用IF而不是case使其变短)@t-clausen.dk您不能在选择中使用IF
。至于反转,你的意思是当subtitle=lag(subtitle,1)。。。然后是0还是1
?这是可行的,只是不平等是我首先想到的tried@t-clausen.dk这确实更好,因为它在每次孤岛更改中返回1
(subtitle=lag(subtitle)over(按名称顺序按日期划分),0,1)抱歉缺少一个F