我有一系列可以按group_id
示例记录:
╭───╥──────────┬───────────────────╮
│id ║ group_id │ position_in_group │
╞═══╬══════════╪═══════════════════╡
│ 1 ║ 2 │ null │
│ 2 ║ 1 │ null │
│ 3 ║ 1 │ null │
│ 4 ║ 1 │ null │
│ 5 ║ 2 │ null │
│ 6 ║ 2 │ null │
│ 7 ║ 3 │ null │
│ 8 ║ 3 │ null │
│ 9 ║ 3 │ null │
└───╨──────────┴───────────────────┘
我想为每条记录设置position_in_group
。如果我GROUP BY group_id
,它就是组内记录的位置。
例如:
在ID为1的组中,id = 2的记录是第一个,因此其position_in_group
将为1.
决赛桌将是:
╭───╥──────────┬───────────────────╮
│id ║ group_id │ position_in_group │
╞═══╬══════════╪═══════════════════╡
│ 1 ║ 2 │ 1 │
│ 2 ║ 1 │ 1 │
│ 3 ║ 1 │ 2 │
│ 4 ║ 1 │ 3 │
│ 5 ║ 2 │ 2 │
│ 6 ║ 2 │ 3 │
│ 7 ║ 3 │ 1 │
│ 8 ║ 3 │ 2 │
│ 9 ║ 3 │ 3 │
└───╨──────────┴───────────────────┘
我有什么方法可以在SQL查询中执行此操作吗?
答案 0 :(得分:1)
一种方法是使用变量。在MySQL中有点挑战,但它看起来像这样:
set @g := -1;
set @rn := 0;
update t
set position_in_group = (@rn := if(@g = group_id, @rn + 1,
if(@g := group_id, 1, 1)
)
)
order by group_id, id;
注意:您需要从update
语句中单独初始化变量,因为MySQL在同一update
语句中不支持连接和排序。
答案 1 :(得分:0)
无需存储此数据......
create view v_table as
select b.*
from banned b
where unixtime < UNIX_TIME();
......但如果你真的想......
SELECT id
, group_id
, rank
FROM
( SELECT id
, group_id
, CASE WHEN group_id = @prev THEN @i:=@i+1 ELSE @i:=1 END rank
, @prev:=group_id prev
FROM my_table x
, (SELECT @i:=1,@prev:=null) vars
ORDER
BY group_id
, id
) a
ORDER
BY id;
答案 2 :(得分:0)
此解决方案由其他用户abcdn实施,请参阅https://stackoverflow.com/a/32105418/3762855
SELECT a.id, a.group_id, (
SELECT count(*) from groups b where a.id >= b.id AND a.group_id = b.group_id
) AS row_number FROM groups a;
答案 3 :(得分:0)
我找到了一种方法来使用纯SQL执行此操作,并且没有使用自联接的变量:
UPDATE my_table
JOIN (
SELECT c.aid AS id, COUNT(*)-1 AS position_in_group
FROM (
SELECT a.id AS aid, b.id AS bid, a.group_id
FROM my_table AS a
JOIN my_table AS b ON (a.group_id=b.group_id AND a.id >= b.id)
) AS c
GROUP BY c.aid
) AS d ON my_table.id = d.id
SET my_table.position_in_group = d.position_in_group;
我自己加入表格来创建匹配对(同一组中的记录),没有重复对。 然后我只计算那些按左记录的id分组的对。