首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >密集等级,按A列划分,因B列的变化而增加,但按C列排序

密集等级,按A列划分,因B列的变化而增加,但按C列排序
EN

Stack Overflow用户
提问于 2018-10-08 08:18:18
回答 1查看 642关注 0票数 1

我有一张这样的桌子

代码语言:javascript
运行
复制
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

我希望在副标题发生更改时增加一个列,如下所示:

代码语言:javascript
运行
复制
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

问题是,如果我在Dense_rank()上(按名称、顺序、字幕进行分区),那么这个组不仅会将所有字幕分成一个组,而且还会删除日期排序。我也尝试过使用延迟函数,但是当您试图增加列时,这似乎并不是很有用。

有什么简单的方法可以做到这一点吗?

请记住,我使用的表有数百个不同的名称。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-08 08:53:57

快速回答

代码语言:javascript
运行
复制
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

解释

你要求的不是排名。在严格按日期排序的序列中,名称和字幕是相同的,您正在尝试使用探测“岛屿”

为此,您可以将当前行的值与前一行的值进行比较。如果它们匹配,你就在同一个“岛”里。如果没有,就有一个开关。每次检测到变化时,您都可以使用它来发出例如1

这就是:

代码语言:javascript
运行
复制
CASE WHEN subtitle != LAG(subtitle,1) OVER (PARTITION BY name ORDER BY date) 
     THEN 1 

一旦有了这个值,就可以使用一个正在运行的总数计算更改的数量:

代码语言:javascript
运行
复制
sum(num) over (partition by name order by date) AS Group_Number

这将生成从0开始的值。要获得从1开始的数字,只需添加1:

代码语言:javascript
运行
复制
1+sum(num) over (partition by name order by date) AS Group_Number

更新

正如T. Clausen在评论中解释的那样,反向比较将消除+1

代码语言:javascript
运行
复制
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

这也是一个更好的方法来检测岛屿,即使在这种情况下的结果是相同的。第一个查询将产生以下结果:

代码语言:javascript
运行
复制
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

第二个查询返回:

代码语言:javascript
运行
复制
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,包括边界

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52698085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档