1

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

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:这是一个例子:

现存的:

名字,姓氏,总和(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 关联的 sum(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
4

1 回答 1

2

SQL Fiddle 上的工作示例: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;
于 2012-08-27T19:59:19.093 回答