我想在我管理的数据库中的表中重新分配一些值。
Firstname(varchar), Lastname(varchar), Date(date), Icecream_consumed(int)
Firstname,Lastname和Date的组合构成此表的主键。更改此表的结构不是一种选择。
数据库中有80个Firstname和LastName的唯一组合,但是我希望将该数字减少到5,并将总数较少的Icecream_consumed添加到总数最高的记录中。因此,只有前5个FirstName和LastName组合具有所有Icecream_consumed计数。
例如,如果我执行查询:
SELECT Firstname, Lastname, SUM(Icecream_consumed)
FROM table_name
GROUP BY Firstname, Lastname
ORDER BY SUM(Icecream_consumed);
我希望它只有5个结果,而不是80个。如何在不手动更新每个记录的情况下修改表中的记录以反映这些结果?简单的更新将无法正常工作,因为它将插入具有相同主键的现有记录。
编辑:我注意到列ID有点含糊不清。所以我从这个例子中删除了它。EDIT2:这是一个例子:
现有:
名字,姓氏,SUM(Icecream_consumed)
John Doe 1500
Joe Doe 1400
Alex Foo 1111
John Foo 1000
Ben Foo 999
Sue Cool 500
Bill Smith 200
Ben Smith 150
我想更改表格,以便与sue,cool,bill smith和ben smith相关联的总和(icecream_consumed)值与john doe相关联,这样只有5个结果可见。但是,如果我试图将所有记录更新为sue cool而不是john doe,则会与主键发生冲突,因为它们在相同的日期都可能具有icecream_consumed的值。 结果可能如下:
John Doe 2000
Joe Doe 1600
Alex Foo 1261
John Foo 1000
Ben Foo 999
答案 0 :(得分:2)
关于SQL小提琴的工作示例:http://sqlfiddle.com/#!2/0e8ab/1
因为如果子选择与更新中的子表相同,MySql无法在更新语句中运行子选择,则需要先将数据临时复制到另一个表中 - 所以当数据仍然存在时不要运行它进入数据库,因为它不是原子操作。您需要先使用数据库关闭所有应用程序。
-- Create a copy of the data
CREATE TABLE table_name_copy SELECT * FROM table_name;
-- Update the rows with the most Icecream_consumed to have the total
UPDATE table_name t1 SET t1.Icecream_consumed = (
SELECT SUM(t2.Icecream_consumed)
FROM table_name_copy t2
WHERE t2.Firstname = t1.FirstName AND t2.Lastname = t1.Lastname
)
WHERE id = (
SELECT id
FROM table_name_copy t2
WHERE t2.Firstname = t1.FirstName AND t2.Lastname = t1.Lastname
ORDER BY Icecream_consumed DESC LIMIT 1
);
-- Delete the other rows that don't have the new totalled Icecream_consumed
DELETE FROM table_name
WHERE id != (
SELECT t2.id
FROM table_name_copy t2
WHERE t2.Firstname = table_name.FirstName AND t2.Lastname = table_name.Lastname
ORDER BY Icecream_consumed DESC LIMIT 1
);
-- Remove the copied table
DROP TABLE table_name_copy;