sqlでできる!二つの絞りこみ。whereとhavingについておさらい

製作 プログラム

最終更新日:2019/10/29

ラムネグから一言:寝る前に読むとくだらなすぎて逆に寝れると好評なすごい適当なブログをこっちではじめてます.

mysqlにはwhereとhavingという二つの絞り込み機能があります。

ていうかなんで二つ?一つでいいでしょ?とわたしも思っていました。ということでここでは自戒の念も込めてsqlで使える二つの絞り込みである「where」と「having」について両者の違いやタイミングによってどっちを使うべきなのかを紹介しておきますね。

  1. 有名な「where」句
  2. マイナー?「having」句
  3. SQL文の実行順序
  4. 本題のWHEREとHAVINGの違い
  5. GROUP BY句って?
  6. GROUP BYした値を絞り込みたいときはhaving!
  7. まとめ

有名な「where」句

mysqlでwhere句といえばめっちゃ有名ですよね。SELECTしてFROMしてWHEREで条件絞り込む!みたいな一番よく使うSQL文だと思います。

こんな風に条件で絞り込んでレコードを取得したい場合はhavingよりもwhereの方を使うべきだと思います。(わたしはデータベース専門のデータベーシストじゃないので深く考えていくとhavingを使うべきタイミングというのもあるのかもしれません。)

マイナー?「having」句

わたしはずっとwhereだけ使ってればいいくらいの単純な絞り込みしかしてなかったのでhavingの存在は知ってたんですが何をする命令なのかはつい最近まで知りもしませんでした。

んでhavingについて調べてみるとなんとこいつも条件絞り込みができるという…。んん?whereとどう違うのよ?っていうのがファーストインスピレーション。

この部分を理解するにはSQL文の実行順序を知る必要があるようです。

SQL文の実行順序

SQL文は書いた順序で実行されるわけじゃないんですよね。例えば「SELECT~FROM~WHERE~」って書いても「FROM~WHERE~SELECT~」って書いてもおんなじってコト。

これも基本的には上から下に書いた順番に動くプログラミングをしてたりするとけっこう意外なんですが、データベースはそういうもんみたい。

…さっ!んじゃ肝心のSQLの実行順序です。

  1. FROM
  2. ON
  3. JOIN
  4. WHERE
  5. GROUP BY
  6. HAVING
  7. SELECT
  8. DISTINCT
  9. ORDER BY
  10. LIMIT

つまりSQL文をどんな順序で書いても絶対にFROM句から実行されていくってコト。

本題のWHEREとHAVINGの違い

さっきの実行順序をもう一回見てみるとWHEREは4番目、HAVINGは6番目です。

もう少し掘り下げるとWHEREはGROUP BYをする前に実行されるのでGROUP BYした結果については絞り込めないんです。

…つまり「GROUP BY」した結果を絞り込みたいならHAVINGを使うべきでそうじゃないならWHEREを使うべきってコトなんです。

GROUP BY句って?

「GROUP BY」句は特定のカラムでグループにするための命令。

よくあるくだものデータベース(よくある?)で例えるなら、リンゴやぶどうなどくだものの「種類」で、さんつがるやふじなどの品種をグループ化して種類ごとの最高値段を求めたりとか、くだものの種類ごとの平均値段を求めるとかっていうときにこのGROUP BYを使います。

GROUP BYをしただけでは何も求まらないのでSELECTで何を求めたいのかMAXとかCOUNTとかAVGとかで指定します。下の例ではくだものの種類ごとに最大の値段が求まります。

SLECT MAX(値段) FROM くだものテーブル GROUP BY 種類

GROUP BYした値を絞り込みたいときはhaving!

結局、havingを使うのはGROUP BYを使った値に対して絞り込みをかけたいときだけだと思っとけばいいと思います。それ以外はぜんぶwhereと。

さっきの例でいうとMAX(値段)の値がいくつ以上だったらレコードを取得したい!ってことがあると思います。高いくだものだけだしたいみたいな。そんな時にHAVINGを使います。

SLECT MAX(値段) AS max_price FROM くだものテーブル GROUP BY 種類 HAVING max_price > 500

この例だとくだものの種類ごとの最大値段が500円よりも上だったらレコードを出力するようになります。

例えば、

  1. りんご―ふじ―120円
  2. りんご―さんつがる―150円
  3. ぶどう―巨峰―600円
  4. ぶどう―ピオーネ―400円

だったらリンゴの最大値は150円だけど500円より高くないから出力されず、結果ぶどうの最大値である「600円」だけが出力されます。

まとめ

ここではmysqlのwhereとhaving句の違いとどのタイミングで使うべきなのかについて紹介しました。

結論だけ書くとGROUP BYを指定していてMAXとかAVGとかでグループごとに計算してる、その計算結果について絞り込みたいときだけhavingでそれ以外はぜんぶwhere、て感じです。

条件の絞り込みに2つ作るくらいなら書いた順番で実行してくれたらいいのにと思うんですがダメなんですかね…?

【おしらせ、というか完全なる宣伝】

文体がもうぜんぜん適当すぎてあれだけどものすごい自由に書いてるブログ「檸檬だくだく」もよろしく.寝る前に読める恐ろしくくだらないやつです.

こんなにも一ミリも目を引かれないタイトルを取り扱ってます: ココア20g / ハイチュウとかってさ / なぜ米と小麦を食べようと思ったのかの謎 /