- ベストアンサー
重複データがあったらその中のひとつは表示したい
MYSQLの構文について教えてください。 例えば下記のようなデータがあり name|point a|50 b|40 c|45 a|60 b|55 これをポイント順に並べ替えて抽出したいのですが、同一の名前が あった場合はポイントの高いデータだけを抽出したいと思っています。 (下記のように) name|point a|60 b|55 c|45 これをスムーズに行うスマートな構文とかありますでしょうか?
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
私が使っている環境(バージョン5.0.19)では、期待した結果となるようです。 SQLを以下の例のようにしてみてはいかがでしょうか? SELECTしているのはpoint列そのものではなくて、min関数の結果なので、その結果でソートするという指定です。 【例1】 select name,min(point) from result where qcount='3' group by name order by 2; 【例2】 select name,min(point) as pnt from result where qcount='3' group by name order by pnt;
その他の回答 (6)
- chukenkenkou
- ベストアンサー率43% (833/1926)
>ポイントが少ない順に並べ替えて抽出、 >同一の名前があった場合はポイントの小さいデータだけを抽出 並べ替えは、抽出した結果に対して行うものです。 やりたいことは、ポイント順に表示ではなく、名前順に表示なのでは? そうであれば、order byでpoint列ではなくname列を指定すればいいだけですが?
お礼
どうもです。 いやいやポイントの小さい順にしたいのです。 同じ名前の場合は小さい物がその人のポイントとして評価したいのです。 なのに、aの中では一番小さいのが選ばれるのですが、全体の4人の 比較ではそのaの一番小さなデータが取り扱われないのです・・。
- chukenkenkou
- ベストアンサー率43% (833/1926)
#2~#4回答者です。 count関数にdistinctを指定し、group byは指定しないことで希望の結果が得られます。 select count(distinct name) as num from result where qcount='3'
お礼
回答ありがとうございます。ちょっと別用事が入ってしまいましてお礼が遅れてしまったことを深謝いたします。chukenkenkouさんのご指摘の通りで、満足した結果を得ることができました。 と・こ・ろ・が・・・ 一番最初の質問で name|point a|30 b|40 c|45 a|47 b|55 d|50 をポイントが少ない順に並べ替えて抽出、同一の名前があった場合は ポイントの小さいデータだけを抽出したいと思い(下記のように) name|point a|30 b|40 c|45 d|50 SELECT name, min(point) FROM result where qcount = '3' group by `name` order by point としたところ、 name|point b|40 c|45 a|30 d|50 となってしまいます。 なんか訳わからなくなってきた・・・(T.T)
- chukenkenkou
- ベストアンサー率43% (833/1926)
#2,#3回答者です。 >この抽出したデータ数を知りたいのですが、 得たいデータ数はname列の値毎の件数でしょうか? 記述されたSQLではname列の値毎に件数が得られるはずですが? count(name)だけではname列の値毎の件数だけ表示されるので、どのname列の値に対してのものか分からないと思います。 select name,count(name) from result where qcount='3' group by name のようにしてname列の値も表示してはいかがでしょうか? >としてはダメでした。 「ダメ」という意味が上述の内容でないなら、「どのような結果を期待しているのに、どうなるのか」を補足説明願います。
お礼
すいません。 書き方がわるかったようで。 質問にあったような結果 name|point a|60 b|55 c|45 を得られた時、データ数は3(ようはa,b,cの3件)であることを 知りたいのです。(教えていただいたクーリエを行う前に) すいません。よろしくお願いいたします。
- chukenkenkou
- ベストアンサー率43% (833/1926)
#2回答者です。 例えば以下のように指定します。 【SQL例】 SELECT name, max(point), qcount FROM result where qcount = 3 group by name order by point selectで「select name,point,qcount from ~ group by name ~」と指定するのは問題があります。 標準SQLや多くのRDBMSの実装では、group by指定時、selectで選択できる列はgroup byで指定した列か集合関数(max,countなど)に限られます。MySQLでは拡張仕様として、group byで指定していない列も指定できますが、その列の値はグループ化した結果、一意に定まるようにしなければ「結果は不定であり保証しない」となっています。 name列でグループ化しか結果、各name列の値のpoint列は一意にならないので、前提条件を満たしていないことになります。 各name列の値ごとの最大値を得たいとのことなので、max(point)を指定してください。 一方、qcount列は「qcount=3」で一意な値に絞り込むとのことなので、上述の条件を満たしています。 ところでqcount列のデータ型は文字でしょうか?それとも数値でしょうか?MySQLは数値列に対して「列名='3'」、文字列に対して「列名=3」のような指定が可能で、自動的にキャストしてくれます。しかし、キャストのオーバヘッドが多少なりとも発生するでしょうから、データ型に合わせた指定をした方がいいと思います。
お礼
ありがとうございます。無事、思い通りの結果を得ることができました。すいません、もうひとつだけよろしいでしょうか? この抽出したデータ数を知りたいのですが、 SELECT count(name) as num FROM result where qcount = '3' group by name としてはダメでした。これは何が問題なのでしょうか?
- chukenkenkou
- ベストアンサー率43% (833/1926)
group byとmax関数を使いましょう。 select `name`,max(`point`) from 表名 group by `name`
お礼
さっそくありがとうございます。 実はちょっと補足があって質問した表はqcount=3で抽出した後です。 それを質問の条件でさらに絞り込みたいのですが・・・ SELECT name, point, qcount FROM result where qcount = '3' order by point のどこにgroup by `name`を入れればいいのでしょう? ワーニングが出てうまく抽出されていないようです・・泣
- tom11
- ベストアンサー率53% (134/251)
こんにちは、 キーワード sql max で、検索すると、ヒットしますよ。
お礼
http://oshiete1.goo.ne.jp/qa2298944.html というサイトを教えてgoo内で探しました。 ANo2でも書いたのですが、どうもうまくヒットしません。うーん。
お礼
ありがとうございました。例1・2共に希望する結果を 得ることができました。長い間ありがとうございました。