SELECTステートメントを使用してデータを取得していると、重複する行を1行にまとめて取得したい場合があります。
例えば、売り上げを管理するテーブルにある顧客情報を取得する際に、特定の期間の売り上げの内、どの顧客に対して売り上げがあったかを知りたい場合などです。
このような場合にSQLでは「DISTINCT(ディスティンクト)」というキーワードを使用することで、同じ値を持つ行を1行にまとめることができます。
そこで今回は、SQLのSELECTステートメントで使用するDISTINCTについて紹介します。
目次
DISTINCTの構文
DISTINCTは、SELECTステートメントで使用します。
SELECTステートメントではSELECTの後の取得する列名を指定しますが、DISTINCTはSELECTと列名の間に記述します。
1 |
SELECT DISTINCT 列名1, 列名2, 列名3... FROM テーブル名 |
例えば、冒頭の売上データを取得する場合であれば、以下のようになります。
1 2 3 4 |
SELECT DISTINCT 顧客 FROM 売上 |
SELECTの実行に使用するサンプルテーブル
本記事では、DISTINCTを指定したSELECTステートメントでデータを取得するテーブルとして、以下の「氏名」テーブルを使用します。
列定義
列名 | データ型 | NULL許容 |
---|---|---|
姓 | nvarchar(20) | No |
名 | nvarchar(20) | No |
テーブルを作成するCREATE文(SQL)
1 2 3 4 5 |
CREATE TABLE 氏名 ( 姓 nvarchar(20) NOT NULL, 名 nvarchar(20) NOT NULL ); |
テーブルにデータを挿入するINSERT文(SQL)
1 2 3 4 5 |
INSERT INTO 氏名 (姓, 名) VALUES ('山田', '太郎'), ('山田', '花子'), ('山田', '太郎'); |
DISTINCTを使用したデータの取得例
作成した「氏名」テーブルに対して、まずはそのままデータを取得しています。
1 2 3 4 |
SELECT 姓, 名 FROM 氏名 |
姓 | 名 |
---|---|
山田 | 太郎 |
山田 | 花子 |
山田 | 太郎 |
次にDISTINCTキーワードを指定してデータを取得します。
1 2 3 4 |
SELECT DISTINCT 姓, 名 FROM 氏名 |
姓 | 名 |
---|---|
山田 | 花子 |
山田 | 太郎 |
同姓同名の「山田太郎」さんのレコードが1行にまとめられて、「山田花子」さんと「山田太郎」さんの2件のデータが取得されていることが確認できます。
次は取得する列に「姓」のみを指定データを取得してみます。
1 2 3 4 |
SELECT DISTINCT 姓 FROM 氏名 |
姓 |
---|
山田 |
「氏名」テーブルのすべてのレコードの「姓」が「山田」なので、今度はすべてのレコードが1行にまとまってデータが取得されていることが確認できます。
DISTINCTを指定したSELECT文では、列挙した列名にの値が重複するものは、すべて1行にまとめてデータが返されます。
ここでは簡単な例をもとにDISTINCTの使い方をご紹介しましたが、DISTINCTは何階層にも及ぶサブクエリを持つような複雑なクエリが返す結果の重複する行を1行にまとめて取得する場合などにとても重宝します。
DISTINCTでまとめた結果のレコード数を取得する
「DISTINCT」を使用することで重複する行を1行にまとめることができますが、DISTINCTでまとめた結果のレコードの数を取得したい場合もあります。
ここでは、DISTINCTでまとめた結果として取得されるレコード数(件数)を取得する方法について紹介します。
DISTINCTでまとめる列が1つの場合
DISTINCTでまとめる列が1つの場合は、以下の構文でレコードの件数を取得することができます。
1 |
SESLECT COUNT(DISTINCT 列名) FROM テーブル名 |
「氏名」テーブルの「姓」列を指定する場合だと以下のようになります。
1 2 3 4 |
SELECT COUNT(DISTINCT(姓)) AS 件数 FROM 氏名 |
上記のSQLを実行すると、結果の「件数」列(「件数」の別名を付けた列)には「1」が返されます。
件数を取得する対象となっているのは、「姓」が「山田」の1レコードになります。
DISTINCTでまとめる列が2つ以上の場合
DISTINCTでまとめる列が2つ以上の場合は、まとめる列が1つの場合と少し異なります。
COUNT関数の引数にDISTINCTを指定する部分は同じですが、列名が複数になるので少し工夫が必要になります。
DISTINCTでまとめる列が複数の場合は、以下の構文でレコードの件数を取得することができます。
1 |
SELECT COUNT(DISTINCT CONCAT(列名1, 列名2, 列名3...) FROM テーブル名 |
「氏名」テーブルの「姓」列と「名」列を指定する場合だと以下のようになります。
1 2 3 4 |
SELECT COUNT(DISTINCT CONCAT(姓, 名)) FROM 氏名 |
上記のSQLを実行すると、結果の「件数」列(「件数」の別名を付けた列)には「2」が返されます。
件数を取得する対象となっているのは、「姓」と「名」の組み合わせが「山田花子」と「山田太郎」の2つのレコードになります。
補足
本記事でご紹介したDISTINCTを使用したデータの取得と同様の結果は、「GROUP BY」キーワードを使用することでも実現できます。
1 2 3 4 5 6 |
SELECT 姓, 名 FROM 氏名 GROUP BY 姓, 名 |
1 2 3 4 5 6 |
SELECT 姓 FROM 氏名 GROUP BY 姓 |
GROUP BYを使用したデータの取得例については、以下の記事をご覧ください。