.1 はじめに
- SQL Serverで重複行の削除をDISTINCT, GROUP BY、副問合せを使用せずに行いたい
- SQLの自己結合を使用して重複行を削除したい
2. 開発環境
- SQL Server 2022
3. テストデータ
- Sales (売上)
ProductID | SaleDate | Amount |
---|---|---|
100 | 2025/01/01 | 100 |
100 | 2025/01/02 | 200 |
100 | 2025/01/03 | 300 |
200 | 2025/02/01 | 500 |
200 | 2025/02/02 | 600 |
4. SQLサンプル
- SaleDate(売上日)が最新の行のみ取得して、重複行を削除する
SELECT
Sales1.*
FROM
Sales Sales1
LEFT JOIN Sales Sales2
ON Sales1.ProductID = Sales2.ProductID
AND Sales1.SaleDate < Sales2.SaleDate;
WHERE
Sales2.SaleDate IS NULL;
- 処理結果
ProductID | SaleDate | Amount |
---|---|---|
100 | 2025/01/03 | 300 |
200 | 2025/02/02 | 600 |
5. 処理の流れ
5.1. Sales (売上)を自己結合する
- 結合条件の符号を変更すると最初、最後を切り替えできる
SELECT
Sales1.*
, Sales2.*
FROM
Sales Sales1
LEFT JOIN Sales Sales2
ON Sales1.ProductID = Sales2.ProductID
AND Sales1.SaleDate < Sales2.SaleDate -- 最後を取得
-- AND Sales1.SaleDate > Sales2.SaleDate -- 最初を取得
- 処理結果
ProductID | SaleDate | Amount | ProductID_1 | SaleDate_1 | Amount_1 |
---|---|---|---|---|---|
100 | 2025/01/01 | 100 | 100 | 2025/01/02 | 200 |
100 | 2025/01/01 | 100 | 100 | 2025/01/03 | 300 |
100 | 2025/01/02 | 200 | 100 | 2025/01/03 | 300 |
100 | 2025/01/03 | 300 | NULL | NULL | NULL |
200 | 2025/02/01 | 500 | 200 | 2025/02/02 | 600 |
200 | 2025/02/02 | 600 | NULL | NULL | NULL |
5.2. 結合できない行のみ取得する(重複行を削除)
SELECT
Sales1.*
, Sales2.*
FROM
Sales Sales1
LEFT JOIN Sales Sales2
ON Sales1.ProductID = Sales2.ProductID
AND Sales1.SaleDate < Sales2.SaleDate -- 最後を取得
-- AND Sales1.SaleDate > Sales2.SaleDate -- 最初を取得
WHERE
Sales2.SaleDate IS NULL;
- 処理結果
ProductID | SaleDate | Amount | ProductID_1 | SaleDate_1 | Amount_1 |
---|---|---|---|---|---|
100 | 2025/01/03 | 300 | NULL | NULL | NULL |
200 | 2025/02/02 | 600 | NULL | NULL | NULL |
6. 参考文献