質問: select distinctについて sql文の質問です。フィールドがtable1に100つあるとします。 select distinct xyz from table1という文があるとします。 これだとxyzのフィールドしか参照していないことになると思います。 そうではなくて、他の99フィールドの値も参照(データにアクセスしたい)したいと思っています。 select distinct xyz, * from table1とselect * from table1みたいなことをやりましたがエラーが発生しました。他の99フィールドを参照する方法はあるでしょうか?
回答: distinctは、最も単純でかつやや不正確な意味は「あるテーブルの中身を取ってくる時に列を絞ったら同じ行が複数出てきたから一つだけにしましょう。」という事だよね。 例:ある講義を、ユーザーが何回受講したか登録するテーブルd_jukou。pkはclassidとuseridとしよう。 | classid | userid | times | | 1 | a | 20 | | 1 | b | 1 | | 2 | b | 99 | | 2 | c | 2 | この中から「誰かに一回でも受講された講義」一覧を作りたい。 select classid from d_jukou この時、1をaさんbさんが、2をbさんcさんが受講しているので1も2も2件出てきますな。ここで欲しいのは講義一覧なのでそういう重複を省きたいわけだ。 select distinct classid from d_jukou これで受講した人数に関わらず各講義が1回ずつ現れるようになる。さて、これをuseridとtimesも含めるとどうなるだろう。 select distinct classid, userid, times from d_jukou 講義が同じでもユーザーと回数が違うレコードがあるのでそれらは重複でなく、当然省略されない。なので > これだとxyzのフィールドしか参照していないことになると思います。 xyzのフィールドしか参照しなくてそこで重複が出るから重複を一回ずつにするのがdistinctの目的だ。仮にdistinctで重複を省いた一覧を作った後それを元のテーブルと結合(inner join)したとしても、せっかく省かれた重複がまた元通りに結合されるのでまったく意味がない。重複を省いた後で他の99フィールドを参照する時に、省かれたどっちを参照したいのかdbmsは分からないからね。なので、それを、たとえば「重複があった場合は一旦重複を省いて1件ずつにした後、xyz列の値が同じものの中でabc列の値が最も若いものを選択する」などという条件を加える事ができるのであればサブクエリを使って実現できる。そういう条件が無いのであればそもそもdistinctを使うという選択がおかしいって事になる訳です。