Programmingバックエンド開発者、BIアナリスト

SQLで複数のフィルターを使用したレポートを作成する際に、ユニークな条件付き集約を信頼できる方法で実装するにはどうすればよいですか?HAVING、CASE、および集約関数を組み合わせる際の注意点は何ですか?

Hintsage AIアシスタントで面接を突破

回答。

条件付き集約は、レポーティングにおいて古典的な課題です。当初は、異なる指標をカウントするためにフィルター付きの個別クエリが作成されていました。すぐに、集約関数内でのCASEを使用した条件付き集約というよりコンパクトな解決策が登場しました(例:SUM(CASE WHEN ...))。フィルター、グループ化、集計ヘッダーを組み合わせる際に問題が発生する可能性があります:誤った合計値や結果の誤解釈が容易に起こり得ます。

解決策:集約関数内で条件付き集約を使用することです。たとえば、すべての従業員について「処理中」と「完了」を示す注文数を出力する必要があります:

SELECT employee_id, SUM(CASE WHEN status = 'processing' THEN 1 ELSE 0 END) as processing_count, SUM(CASE WHEN status = 'done' THEN 1 ELSE 0 END) as done_count FROM Orders GROUP BY employee_id;

重要な特徴:

  • WHEREフィルターに関係なく、すべての必要な合計が1つのクエリで計算されます。
  • SUM内のCASEは、複雑な多指標レポートの構築を可能にします。
  • HAVINGはすでに集約されたデータに適用され、グループ化の結果をフィルタリングします。

トリックのある質問。

CASE条件がNULLを返すとどうなりますか?

集約関数SUMはNULLを無視します。したがって、CASE WHEN ... THEN 1 ENDを記述すると、欠落した行は考慮されません。常に明示的にELSE 0を指定する方が良いでしょう。

SUM(CASE WHEN status = 'processing' THEN 1 ELSE 0 END)

条件付き集約においてWHEREフィルターがステータスの合計に影響することがありますか?

はい:主要なWHEREがサンプルを制限する場合(例:WHERE region = 'west')、計算はフィルタリングされたデータに対してのみ行われます。全体の合計のためには、サブクエリを使用するか、フィルターを削除してください。

HAVINGを使用してグループ化前の行をフィルタリングできますか?

いいえ。HAVINGは集約されたデータに対してフィルタリングを行います。元の行のフィルタリングはWHEREを介して行います。

一般的な誤りとアンチパターン

  • ELSEが欠落しているため、CASEがNULLを返し、集計値が不正確になります。
  • WHEREとHAVINGを混同して、正しい行が取得できません。
  • CASEを使用した単一のクエリの代わりに複数のクエリを使用します。

実生活の例

ネガティブケース

分析レポートで使用しました:

SUM(CASE WHEN status = 'approved' THEN 1 END)

多くのNULLがあり、最終的な合計は過小評価されました。WHEREフィルターのために必要な行が失われました。

利点:

  • コードが短い。

欠点:

  • 不正確な結果で、ビジネスに誤って報告されました。

ポジティブケース

使用したのは:

SUM(CASE WHEN status = 'approved' THEN 1 ELSE 0 END)

コードは単一のクエリに保たれ、最終的なフィルタはHAVINGによって行われました。

利点:

  • 正確で透明性のある指標。
  • 新しいステータスを簡単に追加できる。

欠点:

  • クエリが長くなるため、フィルターには注意が必要です。