2012-08-27 45 views
1

我想在我管理的数据库的表中重新分配一些值。mysql:使用重复主键添加整数值

Firstname(varchar), Lastname(varchar), Date(date), Icecream_consumed(int) 

其中Firstname,Lastname和Date的组合构成此表的主键。更改此表的结构不是一种选择。

在数据库中共有80个名字和姓氏的独特组合,但我想将该数字降至5,并将总冰淇淋消耗量较小的一些记录添加到总数最多的记录中。因此,只有前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 

我想改变表,以便总和(icecream_consumed )与sue,cool,bill smith和ben smith相关的值与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

你想修改记录(以获得'SUM'更新)而不修改它们(保持相同的主键)?如果没有,“当前”与“想要”的一个小例子将有助于更好地理解你想要达到的目标。 – alfasin

+0

听起来像是一个'插入到x选择......从...重复密钥更新消耗=消耗+ y'的工作 –

+0

杰克你能以上面给出的例子的形式给出你的答案吗?我正在研究“重复键”这个词组,并且您提供的内容似乎会添加值,但我也需要消除较小的记录,因此我们保持相同的总数并且不仅仅是从无处添加新的数字。 –

回答

2

工作SQL小提琴例如:http://sqlfiddle.com/#!2/0e8ab/1

因为MySQL不能在UPDATE语句运行子选择,如果再选择相同表作为一个在更新,你需要首先将数据暂时复制到另一个表中 - 所以当数据仍然进入数据库时,请勿运行此操作,因为它不是原子操作。您需要先关闭任何使用数据库的应用程序。

-- 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; 
+0

这是我没有考虑过的一个选项,它很有意义,很好的工作。我现在想知道是否有办法在不创建临时表的情况下执行相同的操作。 –

+0

我唯一能想到的就是编写一个小脚本或应用程序来完成数据迁移。但说实话,这可能是更多的工作。我已经修复了一些错误,并添加了一个工作示例,以此来显示它的工作原理。 – theon