GROUP BYは行をグループ化しデータを集約するために使用されますが、誤って使用すると深刻なエラーや最適でない動作を引き起こす可能性があります。
重要な細かい点:
例:
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に移動し、集約前に絞り込むことです。