クエリでDISTINCT句を用いることにより、値の重複を取り除くことができます。
また、これと名前が似たDISTINCTROW句というのもあります。「レコードの重複を除く」というはたらきをしますが意味がわかりにくく、あまり知られていません。実際あまり使いどころもないので特に深追いはしませんが、ここで違いが出る実例を確認してみたいと思います。
例として右のようなテーブルを用います。
顧客テーブルと、それらの顧客への販売を記録する販売テーブルがあり、一対多の関係となっています。
顧客テーブルには6人の顧客が登録されていますが、同姓同名の者が2人(佐々木 優斗)いることに注意してください。
販売テーブルには9件の販売記録があります。販売テーブルに記録されている顧客は5人であり、つまり顧客の1人(顧客コード5の岩田 瑠衣)については販売の記録がありません。
クエリのデザインビューです。
まず普通に顧客コードで結合したうえで、顧客テーブルの「氏名」列を抽出してみます。
SQLビューで見ると、このようになっています。
SELECT 顧客テーブル.氏名 FROM 顧客テーブル INNER JOIN 販売テーブル ON 顧客テーブル.顧客コード = 販売テーブル.顧客コード;
データシートビューです。
9件の販売のそれぞれの販売先となった顧客の氏名が表示されています。
次に、上記のSQLにDISTINCT句を加え、値の重複を除いてみることとします。
SQLは次のようになります。
SELECT DISTINCT 顧客テーブル.氏名 FROM 顧客テーブル INNER JOIN 販売テーブル ON 顧客テーブル.顧客コード = 販売テーブル.顧客コード;
データシートビューです。
値の重複が除かれ、レコードは4件となっています。販売の記録がある顧客は5人でしたが、同姓同名の顧客がいるため氏名の値としては4種類となります。よってレコードは4件となります。
最後に、DISTINCT句ではなくDISTINCTROW句を加えてみます。
SQLは次のようになります。
SELECT DISTINCTROW 顧客テーブル.氏名 FROM 顧客テーブル INNER JOIN 販売テーブル ON 顧客テーブル.顧客コード = 販売テーブル.顧客コード;
データシートビューです。DISTINCT句の場合と違い、「佐々木 優斗」という氏名が2回現れており、レコードは5件となっています。
なぜこうなるかを理解するため、最初のクエリ(allクエリ。2~4番目の画像)をもう一度見てください。「佐々木 優斗」という値が4回現れています。これらはすべて顧客テーブルの同じレコードから導かれたものではなく、4回のうち3回は「顧客テーブルの顧客コードが2の佐々木 優斗のレコード」から導かれたものであり、1回は「顧客テーブルの顧客コードが4の佐々木 優斗のレコード」から導かれたものです。販売テーブルの内容を見ると顧客コード2に対する販売記録が3回あり、顧客コード4に対する販売記録が1回あることからこれは明らかです。
DISTINCTROWは「レコードの重複を除く」ものですので、「顧客テーブルの顧客コードが2の佐々木 優斗のレコード」から導かれた3回の「佐々木 優斗」は1つにまとめられますが、「顧客テーブルの顧客コードが4の佐々木 優斗のレコード」から導かれた1回の「佐々木 優斗」はそれと別に残ります。結果的に「佐々木 優斗」が1つにならず、2回現れるというわけです。その他の顧客の氏名についてはすべて単一のレコードから導かれたものですので当然1つにまとめられます。
というわけでDISTINCTROWでは(値ではなく)値のもとになっているレコードを区別してそのレコードの重複を除いている、ということがわかると思います。とはいえ1回読んでもわけがわからないと思いますので、いろいろ試して理解していただきたいと思います。