Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 密集秩,由A列划分,按B列的变化递增,但按C列排序_Sql_Sql Server_Ssms_Gaps And Islands - Fatal编程技术网

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
解释

你问的不是确切的排名。您正试图在严格按日期排序的序列中找到名称和副标题相同的位置

为此,可以将当前行的值与前一行的值进行比较。如果他们匹配,你在同一个“岛”。如果不是,就有一个开关。每次检测到更改时,您都可以使用它发出eg
1

这就是:

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