我有一个“游戏”表,每个游戏都有不同的条目,如下所示:
gameID internalName
1 game1
2 game 1
3 game 2
4 game2
5 game3
等
所以,问题是现在我想要结合游戏标题(空白剥离)相同的情况。在其他情况下,gameID为2的行将与1合并,并被删除。
此外,我想更新其他表中使用gameID作为外键的任何条目,以指向新密钥。
我知道我可以这样做,以获得哪些标题有重复的列表:
SELECT gameID, count(REPLACE(internalName, ' ', '')), internalName FROM games GROUP BY REPLACE(internalName, ' ', '') HAVING count(REPLACE(internalName, ' ', '')) > 1
然而,这并没有真正帮助我实现我需要做的事情。
任何帮助?
答案 0 :(得分:2)
类似的东西可以帮助你开始
select g1.gameID as toKeep, g2.gameID toEliminate
from games g1
inner join games g2 on replace(g1.internalName, ' ', '') = replace(g2.internalName, ' ', '')
where g1.gameID < g2.gameID
但是如果要合并3个项目,这将无法正常工作......
请参阅http://sqlfiddle.com/#!2/fb294/6
但是在存储过程或php(或其他语言)中,你应该能够得到你想要的东西。
<强>更好强>
使用这个,甚至3,或4或5个相同的结果将起作用
select g1.gameID as toKeep, g2.gameID toEliminate
from games g1
inner join games g2 on replace(g1.internalName, ' ', '') = replace(g2.internalName, ' ', '')
where g1.gameID < g2.gameID
and g1.gameID not in (SELECT g4.gameID
from games g4
inner join games g3 on replace(g3.internalName, ' ', '') = replace(g4.internalName, ' ', '')
where g3.gameID < g4.gameID)
http://sqlfiddle.com/#!2/8fb21/1
编辑:(未经测试的)存储过程的示例
CREATE PROCEDURE CLEANGAMENAMES()
BEGIN
DECLARE toKeep, toEliminate INT;
DECLARE cur1 CURSOR FOR
SELECT g1.gameID AS toKeep, g2.gameID AS toEliminate
FROM games g1
INNER JOIN games g2 ON REPLACE(g1.internalName, ' ', '') = REPLACE(g2.internalName, ' ', '')
WHERE g1.gameID < g2.gameID
AND g1.gameID NOT IN (SELECT g4.gameID
FROM games g4
INNER JOIN games g3 ON REPLACE(g3.internalName, ' ', '') = REPLACE(g4.internalName, ' ', '')
WHERE g3.gameID < g4.gameID)
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO toKeep, toEliminate;
UPDATE <anyTable> set gameId = toKeep where gameId = toEliminate;
-- as many tables as you need
DELETE FROM games where gameID = toEliminate;
UPDATE games set internalName = REPLACE(internalName, ' ', '');
END LOOP;
CLOSE cur1;
END;