mysql:使用重复的主键添加整数值

时间:2012-08-27 19:21:48

标签: mysql

我想在我管理的数据库中的表中重新分配一些值。

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

1 个答案:

答案 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;