我有一张这样的表:
id name
0 Bob
1 Alice
2 Bob
3
4 Bob
5 Mary
6 Alice
我需要为每个不同的名称分配一个group_id
:
id name group_id
0 Bob 0 -- Bob's group
1 Alice 1 -- Alice's group
2 Bob 0 -- Bob's group
3 -- no group (NULL)
4 Bob 0 -- Bob's group
5 Mary 2 -- Mary's group
6 Alice 1 -- Alice's group
这可以在MySQL的一行中完成吗?
我知道我可以找到带有自动增量列的唯一名称,然后根据名称加入原始表格 - 但我想知道是否存在更简单/更快的解决方案......
答案 0 :(得分:1)
是的,用例。只需根据表达式添加一个新的计算列,该表达式为name
列的每个字符串值输出适当的值
Select id, name,
case name
when 'Bob' then 0
when 'Alice' then 1
when 'Mary' then 2
-- etc.
end GroupId
From table
如果您事先不知道这些名字,或者有太多名字,请试试这个:
Select id, name,
(select count(distinct name)
from table
where name < t.Name) groupId
From table t
除非在name列上添加索引,否则在大型表上这将非常慢。
要为name = null的行输出null而不是0,请使用:
Select id, name,
case when name is null then null
else (select count(distinct name)
from table
where name < t.Name) end groupId
From table t
答案 1 :(得分:0)
一种方法是 - 如您所建议的那样 - group by
和join
。如果数字不必是连续的:
select t.*, minid as group_id
from t join
(select name, min(id) as minid
from t
group by name
) tt
on not t.name <=> tt.name; -- to handle `NULL`
如果有,请使用变量:
select t.*, minid as group_id
from t join
(select name, min(id) as minid, (@grp := @grp + 1) as group_id
from t cross join
(select @grp := -1) params
group by name
) tt
on not t.name <=> tt.name; -- to handle `NULL`;
您还可以使用两种排序和变量执行整个操作:
select t.*
from (select t.*,
(@grp := if(not @n <=> name, @grp,
if(@n := name, 1, 1)
)
) as group_id
from t
(select @grp := -1, @n := '') params
order by name
) t
order by id;