孤岛和缺口订购问题MYSQL 8.0
我试图使用partition by&row_number()来计算给定日期范围内的连续重复值。本质上,它试图捕获“条纹”,如果条纹中出现中断,则当值再次出现时,计数应重新开始 复制这些结果的代码如下: 这是电流输出 下面是所需的输出孤岛和缺口订购问题MYSQL 8.0,mysql,gaps-and-islands,row-number,mysql-8.0,Mysql,Gaps And Islands,Row Number,Mysql 8.0,我试图使用partition by&row_number()来计算给定日期范围内的连续重复值。本质上,它试图捕获“条纹”,如果条纹中出现中断,则当值再次出现时,计数应重新开始 复制这些结果的代码如下: 这是电流输出 下面是所需的输出 我在这件事上绞尽脑汁已经有一段时间了。任何帮助都将不胜感激您的数据与您的结果不符,因此很难实现您的结果 每日|回复|简短|姓名|行数| :--------- | :------------------ | ------: 2020-09-20 | C | 1 202
我在这件事上绞尽脑汁已经有一段时间了。任何帮助都将不胜感激您的数据与您的结果不符,因此很难实现您的结果 每日|回复|简短|姓名|行数| :--------- | :------------------ | ------: 2020-09-20 | C | 1 2020-09-21 | A | 1 2020-09-22 | B | 1 2020-09-23 | C | 1 2020-09-24 | C | 2 2020-09-25 | A | 1 2020-09-26 | A | 2 2020-09-27 | A | 3 2020-09-28 | A | 4 dbfiddle您可以执行以下操作:
select *,
row_number() over(partition by grp order by daily) as seqnum
from (
select *,
sum(inc) over(order by daily) as grp
from (
select *,
case when lag(response_short_name) over(order by daily) = response_short_name
then 0 else 1 end as inc
from partion_test
order by daily
) x
) y
order by daily
结果:
daily response_short_name inc grp seqnum
----------- -------------------- ---- ---- ------
2020-09-20 C 1 1 1
2020-09-21 A 1 2 1
2020-09-22 B 1 3 1
2020-09-23 C 1 4 1
2020-09-24 C 0 4 2
2020-09-25 A 1 5 1
2020-09-26 A 0 5 2
2020-09-27 A 0 5 3
2020-09-28 A 0 5 4
请参阅运行示例:请参阅我认为您只需要按A.daily排序。您的基本问题是子查询没有IRDER,因为表本质上是未排序的,所以请将ORDER BY添加到subquery@nbk将订单添加到子查询仍然会导致“seqnum”无序有时订单是“优化”的,因此使用额外的限制10000
+------------+---------------------+--------+--+
| daily | response_short_name | seqnum | |
+------------+---------------------+--------+--+
| 2020-09-20 | C | 1 | |
| 2020-09-21 | A | 1 | |
| 2020-09-22 | B | 1 | |
| 2020-09-23 | C | 1 | |
| 2020-09-24 | C | 2 | |
| 2020-09-25 | A | 1 | |
| 2020-09-26 | A | 2 | |
| 2020-09-27 | A | 3 | |
| 2020-09-28 | A | 4 | |
+------------+---------------------+--------+--+
CREATE TABLE partion_test (
daily DATE,
response_short_name VARCHAR(10)
);
INSERT INTO `partion_test` (`daily`, `response_short_name`) VALUES
('2020-09-21', 'A'),
('2020-09-25', 'A'),
('2020-09-26', 'A'),
('2020-09-27', 'A'),
('2020-09-28', 'A'),
('2020-09-22', 'B'),
('2020-09-20', 'C'),
('2020-09-23', 'C'),
('2020-09-24', 'C');
select `daily`,`response_short_name`,
row_number() over (partition by `response_short_name`, grp order by `daily`) as row_num
from (select t.*,
(row_number() over (order by `daily`) -
row_number() over (partition by `response_short_name` order by `daily`)
) as grp
from partion_test t
) t
ORDER BY `daily`
daily | response_short_name | row_num
:--------- | :------------------ | ------:
2020-09-20 | C | 1
2020-09-21 | A | 1
2020-09-22 | B | 1
2020-09-23 | C | 1
2020-09-24 | C | 2
2020-09-25 | A | 1
2020-09-26 | A | 2
2020-09-27 | A | 3
2020-09-28 | A | 4
select *,
row_number() over(partition by grp order by daily) as seqnum
from (
select *,
sum(inc) over(order by daily) as grp
from (
select *,
case when lag(response_short_name) over(order by daily) = response_short_name
then 0 else 1 end as inc
from partion_test
order by daily
) x
) y
order by daily
daily response_short_name inc grp seqnum
----------- -------------------- ---- ---- ------
2020-09-20 C 1 1 1
2020-09-21 A 1 2 1
2020-09-22 B 1 3 1
2020-09-23 C 1 4 1
2020-09-24 C 0 4 2
2020-09-25 A 1 5 1
2020-09-26 A 0 5 2
2020-09-27 A 0 5 3
2020-09-28 A 0 5 4