提问人:Chris 提问时间:12/22/2022 更新时间:12/22/2022 访问量:104
如何为组中的每一行分配顺序值
How to Assign Sequential Value to Each Row in a Group
问:
我有一个MySQL表,其中包含两个组(水果和动物)的数据,我需要在每个组中分配一个从1开始的顺序值
数据的初始状态为:
Fruit Apple NULL
Fruit Orange NULL
Fruit Banana NULL
Animal Dog NULL
Animal Cat NULL
Animal Horse NULL
期望的结果是:
Fruit Apple 1
Fruit Orange 2
Fruit Banana 3
Animal Dog 1
Animal Cat 2
Animal Horse 3
(结果是否按字母顺序排列并不重要;只是每组中有一个从 1 开始的唯一数字)
到目前为止,我已经能够为整个表中的每一行分配一个顺序值(即,范围从 1 到 6),但我想请教如何在组从“水果”变为“动物”时将计数器重置回 1
设置如下:
CREATE TABLE TempData (GroupName VARCHAR(16), ItemName VARCHAR(16), Sequence INT );
INSERT INTO TempData VALUES ('Fruit','Apple',NULL), ('Fruit','Orange',NULL), ('Fruit','Banana',NULL), ('Animal','Dog',NULL), ('Animal','Cat',NULL), ('Animal','Horse',NULL);
这是我目前的剧本
UPDATE TempData
INNER JOIN ( SELECT GroupName, ItemName, (@RowOrder := @RowOrder + 1) NewValue
FROM TempData
INNER JOIN (SELECT @RowOrder := 0) VariableSet ) RowSequencing ON TempData.GroupName = RowSequencing.GroupName AND TempData.ItemName = RowSequencing.ItemName
SET TempData.Sequence = RowSequencing.NewValue;
如果能帮助检测组名称何时更改,以便分配的序列号从 1 开始,我们将不胜感激。
谢谢
答:
2赞
Tim Biegeleisen
12/22/2022
#1
如果您运行的是MySQL 8+,我建议您使用:ROW_NUMBER()
SELECT GroupName, ItemName,
ROW_NUMBER() OVER (PARTITION BY GroupName ORDER BY ItemName) Sequence
FROM TempData
ORDER BY GroupName, ItemName;
我还建议不要将序列保存在实际的表列中。这是因为每次添加或删除数据时,顺序都会在逻辑上发生更改,这可能会迫使您再次更新。
如果必须进行更新,则可以使用更新联接:
UPDATE TempData t1
INNER JOIN
(
SELECT GroupName, ItemName,
ROW_NUMBER() OVER (PARTITION BY GroupName ORDER BY ItemName) rn
FROM TempData
) t2
ON t2.GroupName = t1.GroupName AND
t2.ItemName = t1.ItemName
SET
t1.Sequence = t2.rn;
评论
0赞
Chris
12/22/2022
这很好用,非常感谢。(我在MySQL 8.0.28上)。不幸的是,我有一个业务需求来存储顺序值,但从概念上讲,你所说的是完全有道理的。感谢您的协助!
0赞
Tim Biegeleisen
12/22/2022
如果你需要,我已经给了你一个更新选项。
评论