我有这个表结构
id | status
-----+------+
1 | a |
2 | b |
3 | b |
4 | b |
5 | a |
6 | a |
7 | b |
8 | a |
我有两种状态“a”和“b”。 我需要通过这样的逻辑来命令:对于每两个“a”,显示一个“b”。 所以这样的事情(“a”更重要,所以如果有很多“b”,它们将被留在最后)
id | status
-----+------+
1 | a |
5 | a |
2 | b |
6 | a |
8 | a |
3 | b |
4 | b |
7 | b |
有办法做到这一点吗?
答案 0 :(得分:3)
select id
,status
from (select status
,id
,@prev_status := @status
,@status := status
,@rn := case when @prev_status = status
then @rn + 1
else 1
end as rn
from mytable t1,(select @status:=null,@rn:=0) x
order by status
,id
) t
order by floor((rn-1) / case status when 'a' then 2 else 1 end)
,case status when 'a' then 1 else 2 end
,rn
;
+----+--------+
| id | status |
+----+--------+
| 1 | a |
| 5 | a |
| 2 | b |
| 6 | a |
| 8 | a |
| 3 | b |
| 4 | b |
| 7 | b |
+----+--------+
这有助于您了解解决方案:
(group_id = floor((rn-1) / case status when 'a' then 2 else 1 end)
)
+--------+----+----+----------+
| status | id | rn | group_id |
+--------+----+----+----------+
| a | 1 | 1 | 0 |
| a | 5 | 2 | 0 |
| a | 6 | 3 | 1 |
| a | 8 | 4 | 1 |
| b | 2 | 1 | 0 |
| b | 3 | 2 | 1 |
| b | 4 | 3 | 2 |
| b | 7 | 4 | 3 |
+--------+----+----+----------+
答案 1 :(得分:2)
使用变量枚举值,然后使用一些简单的逻辑:
select id, status
from (select t.*,
(@rn := if(@s = status, @rn + 1,
if(@s := status, 1, 1)
)
) as rn
from t cross join
(select @rn := 0, @s := '') params
where status in ('a', 'b')
order by status, id
) ab
order by (case when status = a then floor( (rn - 1) / 2) else (rn - 1) end),
status, id;