【SQL】DISTINCTとGROUP BY:重複を除外

  • #SQL

どちらも結果から重複が消える

【例文】

/* ① */
SELECT DISTINCT shohin_bunrui FROM Shohin;

 shohin_bunrui 
---------------
 キッチン用品
 衣服
 事務用品
/* ② */
SELECT shohin_bunrui FROM Shohin GROUP BY shohin_bunrui;

 shohin_bunrui 
---------------
 キッチン用品
 衣服
 事務用品

ただし目的が違うので使い分けが必要になる

使い分けの考え方

SELECT文の意味が要件に合致しているか?を考える

  • 「選択結果から重複を除外したい」→ DISTINCT
  • 「集約した結果を求めたい」→ GROUP BY

つまり例文②は

集約関数(COUNTなど)を使っていないのにGROUP BY句を使っているのは筋が通っていない

ということになる (なんのためにグループ化したのか必要性が不明だから)

GROUP BY句の使いどころ

/* 「商品分類」の入っている行を数える */
SELECT COUNT(shohin_bunrui) FROM Shohin;

 count 
-------
     8
/* 8行の中身を、グループごとに数える */
SELECT COUNT(shohin_bunrui) FROM Shohin GROUP BY shohin_bunrui;

 count 
-------
     4
     2
     2
     
/*
   グループ   |                中身                | 件数 
--------------+------------------------------------+------
 キッチン用品 | 包丁、圧力鍋、フォーク、おろしがね |    4
 衣服         | Tシャツ、カッターシャツ            |    2
 事務用品     | 穴あけパンチ、ボールペン           |    2
 */
/* さらに集約キーならSELECT句に書けるので、見やすさ◎ */
SELECT shohin_bunrui, COUNT(shohin_bunrui) FROM Shohin
GROUP BY shohin_bunrui;

 shohin_bunrui | count 
---------------+-------
 キッチン用品  |     4
 衣服          |     2
 事務用品      |     2

DISTINCT ならではの使いかた

SELECT * FROM Shohin;

 shohin_id |   shohin_mei   | shohin_bunrui | hanbai_tanka | shiire_tanka |  torokubi  
-----------+----------------+---------------+--------------+--------------+------------
 0001      | Tシャツ        | 衣服          |         1000 |          500 | 2009-09-20
 0002      | 穴あけパンチ   | 事務用品      |          500 |          320 | 2009-09-11
 0003      | カッターシャツ | 衣服          |         4000 |         2800 | 
 0004      | 包丁           | キッチン用品  |         3000 |         2800 | 2009-09-20
 0005      | 圧力鍋         | キッチン用品  |         6800 |         5000 | 2009-01-15
 0006      | フォーク       | キッチン用品  |          500 |              | 2009-09-20
 0007      | おろしがね     | キッチン用品  |          880 |          790 | 2008-04-28
 0008      | ボールペン     | 事務用品      |          100 |              | 2009-11-11
SELECT
COUNT(shohin_bunrui) AS "のべ件数", 
COUNT(DISTINCT shohin_bunrui) AS "種類の数"
FROM Shohin;

/* のべ何件あるか、何種類あるかがわかる */
 のべ件数 | 種類の数 
----------+----------
        8 |        3

関連記事:【SQL】集約関数(または集合関数)

参考書籍:ミック『SQL 第2版 ゼロからはじめるデータベース操作』(翔泳社)