Programmingデータアナリスト / バックエンド開発者

SQLでのGROUP BY構文を使用する際の落とし穴は何ですか、特に集約や複雑なクエリの最適化に関して?

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

回答。

GROUP BYは行をグループ化しデータを集約するために使用されますが、誤って使用すると深刻なエラーや最適でない動作を引き起こす可能性があります。

重要な細かい点:

  • SELECT句にはGROUP BYの列または集約関数のみが許可されています。
  • 複数のJOINを持つ複雑なクエリでは、重複や不正確な集約が発生する可能性があります。
  • 正式な順序:GROUP BYはWHEREの後、HAVINGの前に実行されます。
  • グループ化列にインデックスがない場合、大量のデータでクエリが非常に遅くなる可能性があります。
  • HAVINGは集約後にフィルタリングし、WHEREはその前にフィルタリングします。

例:

SELECT customer_id, COUNT(*) as orders FROM orders WHERE order_date >= '2024-01-01' GROUP BY customer_id HAVING COUNT(*) > 10;

トリビアの質問。

GROUP BYの後のSELECT句で、GROUP BYにも集約関数にも指定されていないフィールドを参照できますか?

回答: いいえ、これはほとんどのSQL実装(例えば、MS SQL、PostgreSQL)でエラーになります。一部の特定のデータベースでは、ランダムで不正確な値が表示される場合があります(特にMySQLでsql_mode 'ONLY_FULL_GROUP_BY'がオフの場合)が、この挙動は不正確で標準では保証されていません。正しい例:

SELECT department, AVG(salary) FROM employees GROUP BY department;

トピックの微妙な知識を知らないための実際の間違いの例。


物語

eコマースプロジェクトでの「商品別収益」レポートは、SELECT sku, price, SUM(qty) FROM orders GROUP BY skuというクエリで準備されました。 考慮しなかった点:priceがGROUP BYに含まれず、集約関数の外にあったため、MySQLは最初に見つかった価格を返しました。これがプロモーション中にレポートに重大なエラーをもたらしました。修正方法:priceをGROUP BYに追加するか、集約関数を使用することです。


物語

BIプロジェクトでの複雑なレポートは、複数のJOINとGROUP BYを使用して、予定の3分でなく80分かかりました。 分析の結果、GROUP BYのフィールドとフィルタリングにインデックスが不足しており、集約のために巨大な一時テーブルが作成されていました。解決策:インデックスの最適化とクエリのテーブル式による書き換えです。


物語

開発者が非集約ユーザー属性の値をフィルタリングするためにHAVINGを使用しました。 結果として、サーバーはすべてのデータをグループ化し、その後HAVINGによって削除し、パフォーマンスが低下しました。修正方法:このチェックをWHEREに移動し、集約前に絞り込むことです。