值更改时重置行号,但分区中有重复值
Reset Row Number on value change, but with repeat values in partition
我遇到了与这个问题非常相似的问题
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 只是一个小小的调整,但这已经超出了我的能力范围,我设法让它适用于我的数据,但这纯粹是通过替换列和 table名字。不幸的是,没有足够详细的理解来解决我遇到的问题。
我的数据看起来像
custno start_date value
实际上完全一样。每次 'value' 或 'who' 更改时,我都希望 Row/rank 为 1,无论之前是否看到过 value/who。这都是相对于一个custno
。我确实看到 value/who 也可以 return 返回相同值的实例。同样,上面的解决方案处理 'repetition' 就好了......但是对于 custno
我想我只需要以某种方式在某个地方添加某种 custno
分组?只是不确定在哪里或如何
谢谢!
这是一个间隙和孤岛问题,我们可以在这里使用行数差异法:
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 custno, rn1 - rn2 ORDER BY moddate) rn
FROM cte
ORDER BY
custno,
moddate;
为了解释此处使用的行号方法的差异,rn1
只是根据您在上面显示的数据,每个客户从 1 开始的时间顺序序列。 rn2
序列另外被 who
分割。对于每个客户,rn1
和 rn2
之间的 差异 总是具有相同的值。正是由于这种差异,我们然后在整个 table 上取一个行号来生成您真正想要看到的序列。
最后一个 ROW_NUMBER 子句应该是:
ROW_NUMBER() OVER (PARTITION BY custno, who, rn1 - rn2 ORDER BY custno, moddate) rn
尝试将第二条和第四条记录更改为 EMSZC49,您就会明白我的意思了。您随时都会遇到同样的问题,第一个 n 的记录与下一个 n 的记录匹配。
我遇到了与这个问题非常相似的问题 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 只是一个小小的调整,但这已经超出了我的能力范围,我设法让它适用于我的数据,但这纯粹是通过替换列和 table名字。不幸的是,没有足够详细的理解来解决我遇到的问题。
我的数据看起来像
custno start_date value
实际上完全一样。每次 'value' 或 'who' 更改时,我都希望 Row/rank 为 1,无论之前是否看到过 value/who。这都是相对于一个custno
。我确实看到 value/who 也可以 return 返回相同值的实例。同样,上面的解决方案处理 'repetition' 就好了......但是对于 custno
我想我只需要以某种方式在某个地方添加某种 custno
分组?只是不确定在哪里或如何
谢谢!
这是一个间隙和孤岛问题,我们可以在这里使用行数差异法:
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 custno, rn1 - rn2 ORDER BY moddate) rn
FROM cte
ORDER BY
custno,
moddate;
为了解释此处使用的行号方法的差异,rn1
只是根据您在上面显示的数据,每个客户从 1 开始的时间顺序序列。 rn2
序列另外被 who
分割。对于每个客户,rn1
和 rn2
之间的 差异 总是具有相同的值。正是由于这种差异,我们然后在整个 table 上取一个行号来生成您真正想要看到的序列。
最后一个 ROW_NUMBER 子句应该是:
ROW_NUMBER() OVER (PARTITION BY custno, who, rn1 - rn2 ORDER BY custno, moddate) rn
尝试将第二条和第四条记录更改为 EMSZC49,您就会明白我的意思了。您随时都会遇到同样的问题,第一个 n 的记录与下一个 n 的记录匹配。