例題
以下のテーブルのうち、
コード | 日付 |
---|---|
1 | 20210801 |
1 | 20210802 |
2 | 20210701 |
2 | 20210702 |
3 | 20210801 |
3 | 20210802 |
3 | 20210803 |
4 | 20210601 |
UPDATEのケース:コード内で日付が最大のレコード以外の日付を0に更新する
DELETEのケース:コード内で日付が最大のレコード以外のレコードを削除する
以上の条件で更新の対象となるレコードは以下の通り
コード | 日付 | 対象 |
---|---|---|
1 | 20210801 | ○ |
1 | 20210802 | |
2 | 20210701 | ○ |
2 | 20210702 | |
3 | 20210801 | ○ |
3 | 20210802 | ○ |
3 | 20210803 | |
4 | 20210601 |
スキーマ
CREATE TABLE `テーブル`
(`コード` int, `日付` int);
INSERT INTO `テーブル`
VALUES
(1, 20210801),
(1, 20210802),
(2, 20210701),
(2, 20210702),
(3, 20210801),
(3, 20210802),
(3, 20210803),
(4, 20210601);
対象レコードを抽出するSELECT文
SELECT *
FROM テーブル AS Z
WHERE 日付 < (SELECT MAX(日付)
FROM テーブル AS A
WHERE A.コード = Z.コード
)
コード | 日付 |
---|---|
1 | 20210801 |
2 | 20210701 |
3 | 20210801 |
3 | 20210802 |
一般的なSQLの構文
UPDATE文
UPDATE テーブル AS Z
SET 日付 = 0
WHERE 日付 < (SELECT MAX(日付)
FROM テーブル AS A
WHERE A.コード = Z.コード
);
DELETE文
DELETE
FROM テーブル AS Z
WHERE 日付 < (SELECT MAX(日付)
FROM テーブル AS A
WHERE A.コード = Z.コード
);
上記はMySQLでは以下のエラーとなります
You can't specify target table 'Z' for update in FROM clause
DeepLで翻訳すると
FROM句で更新対象のテーブル'Z'を指定できない
MySQLでの対処方法
サブクエリ部分を1階層深くして、更新文のFROM句で指定したテーブルをサブクエリで直接参照しないようにします
UPDATE文
UPDATE テーブル AS Z
SET 日付 = 0
WHERE (コード,日付) IN(SELECT *
FROM (SELECT コード, 日付
FROM テーブル AS Z
WHERE 日付 < (SELECT MAX(日付)
FROM テーブル AS A
WHERE A.コード = Z.コード
)
) SUB
);
DELETE文
DELETE
FROM テーブル
WHERE (コード,日付) IN(SELECT *
FROM (SELECT コード, 日付
FROM テーブル AS Z
WHERE 日付 < (SELECT MAX(日付)
FROM テーブル AS A
WHERE A.コード = Z.コード
)
) SUB
);