PostgreSQLで複数の列でSELECT DISTINCTを行う方法
PostgreSQLで複数の列でSELECT DISTINCTを行う方法
PostgreSQL で複数の列でSELECT DISTINCTを行う方法はいくつかあります。
DISTINCTキーワードを使用する
SELECT DISTINCT 列名1, 列名2, ...
FROM テーブル名;
この方法は、複数の列をカンマ区切りで指定します。
例
SELECT DISTINCT 氏名, 性別, 年齢
FROM 顧客;
このクエリは、顧客テーブルから重複する行を排除し、氏名、性別、年齢の列のみを返します。
GROUP BYを使用する
SELECT 列名1, 列名2, ...
FROM テーブル名
GROUP BY 列名1, 列名2, ...;
この方法は、GROUP BY句でグループ化し、各グループの最初の行のみを返します。
SELECT 氏名, 性別, COUNT(*) AS 件数
FROM 顧客
GROUP BY 氏名, 性別;
このクエリは、顧客テーブルを氏名と性別でグループ化し、各グループの氏名、性別、顧客数 (COUNT(*)) を返します。
EXISTSを使用する
SELECT 列名1, 列名2, ...
FROM テーブル名 t1
WHERE NOT EXISTS (
SELECT *
FROM テーブル名 t2
WHERE t1.列名1 = t2.列名1
AND t1.列名2 = t2.列名2
AND ...
);
この方法は、EXISTSサブクエリを使用して、重複する行を排除します。
SELECT 氏名, 性別
FROM 顧客 t1
WHERE NOT EXISTS (
SELECT *
FROM 顧客 t2
WHERE t1.氏名 = t2.氏名
AND t1.性別 = t2.性別
);
DISTINCTキーワード は、最もシンプルで効率的な方法ですが、GROUP BYやEXISTSよりも柔軟性に欠けます。
GROUP BY は、集計関数と組み合わせることで、より複雑な分析を行うことができます。
-- テーブル作成
CREATE TABLE 顧客 (
氏名 VARCHAR(255) NOT NULL,
性別 VARCHAR(1) NOT NULL,
年齢 INT NOT NULL
);
-- データ挿入
INSERT INTO 顧客 (氏名, 性別, 年齢) VALUES
('山田太郎', '男', 20),
('佐藤花子', '女', 21),
('田中一郎', '男', 22),
('佐藤花子', '女', 21),
('斎藤二郎', '男', 23);
-- SELECT DISTINCT
SELECT DISTINCT 氏名, 性別, 年齢
FROM 顧客;
-- 結果
-- 山田太郎 男 20
-- 佐藤花子 女 21
-- 田中一郎 男 22
-- 斎藤二郎 男 23
SELECT 氏名, 性別, COUNT(*) AS 件数
FROM 顧客
GROUP BY 氏名, 性別;
-- 結果
-- 山田太郎 男 1
-- 佐藤花子 女 1
-- 田中一郎 男 1
-- 斎藤二郎 男 1
SELECT 氏名, 性別
FROM 顧客 t1
WHERE NOT EXISTS (
SELECT *
FROM 顧客 t2
WHERE t1.氏名 = t2.氏名
AND t1.性別 = t2.性別
);
-- 結果
-- 山田太郎 男
-- 佐藤花子 女
-- 田中一郎 男
-- 斎藤二郎 男
実行方法
- PostgreSQLクライアントに接続します。
- 上記のコードをコピーして、新しいクエリウィンドウに貼り付けます。
- クエリを実行します。
- 結果を確認します。
補足
- 上記のサンプルコードは、PostgreSQL 14.2で動作確認しています。
- テーブル名や列名は、環境に合わせて変更してください。
PostgreSQLで複数の列でSELECT DISTINCTを行う他の方法
UNION ALLを使用する
SELECT 列名1, 列名2, ...
FROM テーブル名1
UNION ALL
SELECT 列名1, 列名2, ...
FROM テーブル名2;
この方法は、複数のテーブルから重複する行を排除して結果を返すことができます。
-- テーブル作成
CREATE TABLE 顧客1 (
氏名 VARCHAR(255) NOT NULL,
性別 VARCHAR(1) NOT NULL
);
CREATE TABLE 顧客2 (
氏名 VARCHAR(255) NOT NULL,
年齢 INT NOT NULL
);
-- データ挿入
INSERT INTO 顧客1 (氏名, 性別) VALUES
('山田太郎', '男'),
('佐藤花子', '女');
INSERT INTO 顧客2 (氏名, 年齢) VALUES
('田中一郎', 22),
('斎藤二郎', 23);
-- UNION ALL
SELECT 氏名, 性別
FROM 顧客1
UNION ALL
SELECT 氏名, 年齢 AS 性別
FROM 顧客2;
-- 結果
-- 山田太郎 男
-- 佐藤花子 女
-- 田中一郎 22
-- 斎藤二郎 23
LATERAL JOINを使用する
SELECT t1.列名1, t1.列名2, ...
FROM テーブル名 t1
LATERAL JOIN (
SELECT *
FROM テーブル名 t2
WHERE t1.列名1 = t2.列名1
AND t1.列名2 = t2.列名2
...
) t2 ON TRUE;
-- テーブル作成
CREATE TABLE 顧客 (
氏名 VARCHAR(255) NOT NULL,
性別 VARCHAR(1) NOT NULL,
年齢 INT NOT NULL
);
-- データ挿入
INSERT INTO 顧客 (氏名, 性別, 年齢) VALUES
('山田太郎', '男', 20),
('佐藤花子', '女', 21),
('田中一郎', '男', 22),
('佐藤花子', '女', 21),
('斎藤二郎', '男', 23);
-- LATERAL JOIN
SELECT 氏名, 性別, 年齢
FROM 顧客 t1
LATERAL JOIN (
SELECT *
FROM 顧客 t2
WHERE t1.氏名 = t2.氏名
AND t1.性別 = t2.性別
) t2 ON TRUE;
-- 結果
-- 山田太郎 男 20
-- 佐藤花子 女 21
-- 田中一郎 男 22
-- 斎藤二郎 男 23
WITH句を使用する
WITH 顧客 AS (
SELECT DISTINCT 列名1, 列名2, ...
FROM テーブル名
)
SELECT *
FROM 顧客;
この方法は、WITH句を使用して、中間テーブルを作成してからSELECT DISTINCTを行うことができます。
-- テーブル作成
CREATE TABLE 顧客 (
氏名 VARCHAR(255) NOT NULL,
性別 VARCHAR(1) NOT NULL,
年齢 INT NOT NULL
);
-- データ挿入
INSERT INTO 顧客 (氏名, 性別, 年齢) VALUES
('山田太郎', '男', 20),
('佐藤花子', '女', 21),
('田中一郎', '男', 22),
('佐藤花子', '女', 21),
('斎藤二郎', '男', 23);
-- WITH句
WITH 顧客 AS (
SELECT DISTINCT 氏名, 性別
FROM 顧客
)
SELECT *
FROM 顧客;
-- 結果
-- 山田太郎 男
-- 佐藤花子 女
-- 田中一郎 男
-- 斎藤二郎 男
- UNION ALLは、複数のテーブルから重複する行を排除する場合に便利です。
- LATERAL JOINは、複雑な条件に基づいて重複する行を排除する場合に便利です。
- WITH句は、中間テーブルを作成して複雑なクエリを簡潔に記述する場合に便利です。
- PostgreSQL公式ドキュメント - UNION: [https://
sql postgresql sql-update