1

管理しているデータベースのテーブルのいくつかの値を再配布したいと思います。

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

Firstname、Lastname、およびDateの組み合わせが、このテーブルの主キーになります。このテーブルの構造を変更することはオプションではありません。

データベースには、FirstnameとLastNameの合計80の一意の組み合わせがありますが、その数を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);

80ではなく5つの結果のみにしたいのですが、各レコードを手動で更新せずに、これを反映するようにテーブル内のレコードを変更するにはどうすればよいですか。同じ主キーを持つ既存のレコードが存在する場所に挿入するため、単純な更新は機能しません。

編集:列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に関連付けられたsum(icecream_consumed)値がjohn doeに関連付けられ、5つの結果のみが表示されるように、テーブルを変更したいと思います。ただし、代わりにsuecoolのすべてのレコードを更新してjohndoeにしようとすると、両方のレコードに同じ日付の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 に答える