VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
SELECT DISTINCT は、各結果行が何回現れても、それを 1 回だけ返します。
「この列にはどんな値が現れるか」という形の質問に答えるもので、これは初めて
見るテーブルについて最初に知りたいことであることが多いものです。
始める前に、mysql -u root -p sakila でクライアントを開いてください。
DISTINCT の仕組み
COLUMN_LIST を欲しい列に、TABLE_NAME をテーブルに置き換えます。
DISTINCT は SELECT の直後に置かれ、隣の列ではなく選択リスト全体に適用
されます。この 1 つの事実が、これに関するほとんどの驚きを説明します。
例
- 1 つの列の値
Sakila はすべての映画にレーティングを付けています。これはどのレーティングが
存在するかを尋ねます。
DISTINCT は重複を取り除くだけで、順序については何も言わないため
です。順序が欲しいときは ORDER BY を追加してください。
- 別の列
- 異なる組み合わせ
2 つの列を指定すると、各列の値を別々に得るのではなく、異なる組み合わせを
それぞれ得ます。
並べ替えたレーティングがアルファベット順でない理由
その結果はrating で並べ替えられていますが、G、PG、PG-13、R、NC-17
の順に並んでいます。アルファベット順なら NC-17 は 2 番目に来るはずです。
ORDER BY は正しく動作しており、その理由は列の型にあります。
SHOW COLUMNS はテーブルの列を一覧にし、LIKE の後のパターンがそれを 1 つの
名前に絞り込みます。
rating は ENUM で、固定された値のリストだけを受け入れる列型です。MySQL は
各値をそのリスト内の位置として保存し、その位置で並べ替えるため、ENUM は値が
宣言された順序で並びます。ここでは、宣言された順序は最も制限の緩いレーティング
から最も厳しいものへと並んでいます。
列を追加すると効果がなくなることがある
DISTINCT は行全体を見るため、ほぼ一意な列を追加すると、ほとんど何も
取り除かれません。
rating と title の各
組み合わせも異なり、重複するものは何もありません。ここで DISTINCT が 5 行を
返すことはできません。1,000 個の異なる値を持つ列を求めたからです。多くの行を
レーティングごとに 1 行にまとめるのは別の操作であり、
GROUP BY がそのための句です。
まとめ
- 各結果行を 1 回だけ返すには
SELECT DISTINCTを使います。 - 選択リスト内のすべての列に同時に適用されると考えてください。
- 重複を除いた値を並べ替えたいときは
ORDER BYを追加します。 ENUM列はアルファベット順ではなく宣言された順序で並ぶと考えてください。