问题描述
这是原始的MysqL表:
+----+-----+
| Id | Num |
+----+-----+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
+----+-----+
当我使用select Id,Num,row_number() over(partition by Num) from t
时,MysqL自动中断Num
列的顺序。但是,我想保持Num
列的顺序不变。
具体来说,理想的输出应为:
+----+-----+-----+
| Id | Num | row |
+----+-----+-----+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
| 5 | 1 | 1 |
| 6 | 2 | 1 |
| 7 | 2 | 2 |
+----+-----+-----+
如何编写此MySQL查询?
解决方法
这是一个空白问题。我建议使用行号之间的差异来识别组。
如果id
总是无间隙递增:
select id,num,row_number() over(partition by num,id - rn order by id) rn
from (
select t.*,row_number() over(partition by num order by id) rn
from mytable t
) t
order by id
否则,我们可以使用另一个id
生成自己的增量row_number()
:
select id,rn1 - rn2 order by id) rn
from (
select t.*,row_number() over(order by id) rn1,row_number() over(partition by num order by id) rn2
from mytable t
) t
order by id
Demo on DB Fiddle -对于您的示例数据,两个查询都产生:
id | num | rn -: | --: | -: 1 | 1 | 1 2 | 1 | 2 3 | 1 | 3 4 | 2 | 1 5 | 1 | 1 6 | 2 | 1 7 | 2 | 2,
您可以通过writing your own row_number进行此操作,以更好地控制其分区。
set @prev_num = null;
set @row_number = 0;
select
id,-- Reset row_number to 1 whenever num changes,else increment it.
@row_number := case
when @prev_num = num then
@row_number + 1
else
1
end as `row_number`,-- Emulate lag(). This must come after the row_number.
@prev_num := num as num
from foo
order by id;
,
与Schwern提出的解决方案相同的想法。我发现MySQL的另一种语法风格非常简单且易于使用。
.toBeHidden{
position: relative;
}
.overlay{
position: absolute;
height: 100%;
width: 100%;
background-color: red;
color: white;
}
DB小提琴链接-https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=e04692841d091ccd54ee3435a409c67a