SQLで絞り込み条件を記述する時、最もよく使うのがwhere文でしょう。
そしてgroup by でグルーピングした時に、その条件を絞るときにhavingを使います。
これはSQLの教科書なら、どこにでも載っています。
しかしです。
中には条件を絞るときに、whereで書いても、そのあとgroup by の次に having で書いても、どっちでも書けるときがあります。
じゃあ、どっちでもいいのかな??

そう。それが今回の記事で一番お伝えしたいことです。
実は「違う」のです。
この点についてChatgpt4が明快に答えてくれました。
Whereとhavingは何が違うのか

以下の2種類のコードを比べて、何が違うのか教えてください。
処理の順番が単に違うだけで、出力結果は同じなのでしょうか?
1
SELECT 日付, count(社員名)
from 入退室管理
where 事由区分='3'
group by 日付
2
SELECT 日付, count(社員名)
from 入退室管理
group by 日付
having 事由区分='3'
この2つのコードは処理の順番が異なるだけでなく、出力結果も異なります。
1つ目のコード(1)では、まず「入退室管理」テーブルから事由で区別が「3」のレコードを抽出します。その後、日付ごとにグループ化され、各グループの社員名番号がカウントされます。
2つ目のコード(2)では、まず「入退室管理」テーブルの全ての記録を取得しています。
次に、日付ごとにグループ化され、各グループごとの社員名数がカウントされます。
最後に、HAVING句を使用して、事由により「3」のグループのみを結果に含めます。
コード(1)では、事由により区別が「3」の日付ごとの社員名数が出力されますが、コード(2)では、全ての日付ごとの社員名数が出力され、その後に結果がフィルタリングされ、事由により区別が「3」のものだけが残ります。
計算の順序が違う、ということだね

演算量や計算の負担が少ないのはどっち?

では、先の1と2で、演算量や計算の負担が少ないのはどっちですか?
データの量が大きい場合、実際の処理においては「事由により区別が '3' のレコードのみを対象とする」ことで、処理するレコード数を減らすことができます。それにより、処理するデータの量が少なくなります。
コード(1)では、最初に事由区別が '3' のレコードのみを抽出しています。
この抽出処理により、データベース エンジンは事由区別が '3' に一致するレコードのみを処理することになります。
そして日付ごとにグループ変更し、社員名の数をカウントします。
一方、コード(2)では、最初に全てのレコードを取得しています。
この場合、エンジンは全てのレコードを処理し、日付ごとにグループ化してから、HAVING句を使用して事由で区別が3'に一致するグループのみを結果に含めます。
したがって、コード(1)は事由により区別が「3」のレコードのみを対象にしているため、処理するレコード数が少なくなり、データの量が大きい場合でも演算量や計算の負担が軽減されます。これにより、処理の高速化や効率化が期待できます。
こういう話って、教科書に載ってそうで載っていないよね。
いいこと言うじゃない!
