SSブログ

クエリ WHEREとHAVING [クエリ]

 WHEREは抽出条件を設定する構文ですが、同じような構文にHAVINGというのがあります。
 ACCESSのクエリ作成のGUIは非常に良くできていて、SQLに詳しくなくても、直感的に様々なクエリを作成することができます。
 その便利さゆえ、初心者がやってしまいがちな間違いがHAVINGの使い方です。

 例えば、下図のようなテーブルのデータから、2012/1/3のデータから、金額の合計集計を得たいとします。

 データは日別・担当者別となっていますので、単なる条件抽出だけではなく、集計が必要になります。

 最初に、良くない作成例。

 集計クエリにして、日付でグループ化、金額は合計集計、抽出条件を日付に設定しています。
 これでも正しい結果が得られます。

 ここで、このクエリのSQLを表示させてみます。

 抽出条件を設定した部分は、「HAVING」と言う記述になっています。
 集計クエリではない通常のクエリのように、集計クエリの条件を設定してしまうとこのようになります。

 HAVINGは、集計結果に対して条件を設定する場合に使用する構文です。
 抽出条件を設定するという意味ではWHEREと同じですが、抽出を行うタイミングが異なります。
 上記の例の場合、まず、テーブル全体に対して、日ごとに金額の集計が行われます。
 その後、日付条件で抽出が行われ、結果の内容が選択されます。

 どこが良くないかというと、テーブル全体に対して、日ごとに金額の集計が行われてしまう事です。
 この例の場合、欲しい結果は2012/1/3のデータなので、他の日のデータは必要ありません。それなのに、金額の集計が行われてしまっています。

 これに対し、WHEREで条件を設定すると、まず最初に、テーブルのデータを2012/1/3で絞り込みます。
 そして、2012/1/3のデータのみになった状態で、集計処理が行われます。
 例のテーブルで言えば、HAVINGの方は20件のデータに対して集計を行っているのに対し、WHEREでは5件の集計で済んでいます。
 より効率の良いSQLを作成するには、この辺の事情を理解することが必要になってくると思います。

 クエリデザインで集計クエリを作成する際、WHEREで条件を設定するには、下記のように行います。

 「集計」のドロップダウンリストの項目から「Where条件」を選択します。

 この指定により、抽出条件がWHEREで作成されます。

 実行結果はこのようになります。
 日付列はWhere条件の為の物となるので、結果には表示されなくなります。
 2012/1/3で抽出しているので、実質必要ないと思いますが、必要な場合は、日付列をグループ化で追加することで結果に表示されます。

 今回の例のようなケースは、WHEREでもHAVINGでも目的の結果が得られるため、作成者がその違いに気づきにくい点が問題です。
  テーブルのデータ件数が少ないうちは良いのですが、データが増えてくると、レスポンスが悪化する原因になります。
 テスト段階まではレスポンスに問題が無くても、運用が始まって1年2年と使っていくと、徐々に遅くなっていく、と言うことが起きてしまいます。
 さらに言えば、開発作業のみを請け負った場合、作った当人はいつまでもその影響を知らないままになって、同じ事を繰り返してしまうことになります。

 さて、WHEREを使うのが適切な例をあげましたが、最後にHAVINGを使用する例もあげておきたいと思います。
 データは同じテーブルを使用して、日ごとに金額を集計して、結果が4000より大きいレコードのみを抽出するクエリを作成します。

 日付でグループ化を行い、金額は合計集計を行います。
 金額の抽出条件に「>4000」を設定しています。
 これは、集計前のデータ一件一件に対しての条件ではなく、日付で集計された結果に対する条件になります。

 SQLを確認すると、条件がHAVING構文で作成されています。

 結果はこの通り。
 テーブル全体に対して集計が行われてしまいますが、今回の処理は、まず金額の集計値を出さないことには抽出が行えないので仕方ありません。
 しかし、実際には、「2012年1月のデータを対象に」とか処理範囲を限定して処理を行うと思いますので、その場合はやはりWHERE句で日付をBetweenで抽出してから集計をするのが適切です。

 クエリデザインを使いこなすためには、SQL文の知識も必要です。


nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。
※URL(リンク)は記述できません。

トラックバック 0

トラックバックの受付は締め切りました

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。