重置行号,更改值,但分区中有重复值

问题描述 投票:1回答:1

我遇到了与此问题非常相似的问题T-sql Reset Row number on Field Change

此问题的解决方案是完美的,效果很好。除非我尝试其他多个“ custno”,否则它会崩溃。

我的意思是:

custno      moddate                     who
--------------------------------------------------
581827      2012-11-08 08:38:00.000     EMSZC14
581827      2012-11-08 08:41:10.000     EMSZC14
581827      2012-11-08 08:53:46.000     EMSZC14
581827      2012-11-08 08:57:04.000     EMSZC14
581827      2012-11-08 08:58:35.000     EMSZC14
581827      2012-11-08 08:59:13.000     EMSZC14
581827      2012-11-08 09:00:06.000     EMSZC14
581827      2012-11-08 09:04:39.000     EMSZC49 Reset row number to 1
581827      2012-11-08 09:05:04.000     EMSZC49
581827      2012-11-08 09:06:32.000     EMSZC49
581827      2012-11-08 09:12:03.000     EMSZC49
581827      2012-11-08 09:12:38.000     EMSZC49
581827      2012-11-08 09:14:18.000     EMSZC49
581827      2012-11-08 09:17:35.000     EMSZC14 Reset row number to 1
-- my new rows for example of problem
581829      2012-11-08 09:12:03.000     EMSZC14 1
581829      2012-11-08 09:12:38.000     EMSZC49 1
581829      2012-11-08 09:14:18.000     EMSZC49
581829      2012-11-08 09:17:35.000     EMSZC14 Reset row number to 1

[新custno的引入打破了这个解决方案,它对于一个custno来说是完美的。

with C1 as
(
    select 
        custno, moddate, who,
        lag(who) over(order by moddate) as lag_who
    from 
        chr
),
C2 as
(
    select 
        custno, moddate, who,
        sum(case when who = lag_who then 0 else 1 end) 
            over(order by moddate rows unbounded preceding) as change 
    from 
        C1
)
select 
    row_number() over(partition by change order by moddate) as RowID,
    custno, moddate, who
from 
    C2

我敢肯定,只有一点点调整才能处理多个custno,但是这已经超出了我的能力范围,我设法使其适用于我的数据,但这纯粹是通过替换列和表名来完成的。不幸的是,没有足够详细的理解来解决我遇到的问题。

我的数据看起来像

custno   start_date    value

实际上完全相同。每当“值”或“谁”更改时,我都希望行/等级为1,无论该值/谁以前见过。这都是相对于custno而言的。而且我确实看到了一个值/谁也可以返回相同值的实例。同样,上述解决方案可以很好地解决“重复”问题,但是对于custno

我想我只是需要以某种方式在某处添加按custno进行分组的方式?只是不确定在哪里或如何

谢谢!

sql-server lag row-number ranking-functions partition-by
1个回答
1
投票

这是一个间隙和孤岛问题,我们可以在这里使用行数差异方法:

WITH cte AS (
    SELECT *,
        ROW_NUMBER() OVER (PARTITION BY custno ORDER BY moddate) rn1,
        ROW_NUMBER() OVER (PARTITION BY custno, who ORDER BY moddate) rn2
    FROM chr
)

SELECT custno, moddate, who,
    ROW_NUMBER() OVER (PARTITION BY rn1 - rn2 ORDER BY moddate) rn
FROM cte
ORDER BY
    custno,
    moddate;
© www.soinside.com 2019 - 2024. All rights reserved.