MySQL で SUM()
計算を複数のテーブル結合と組み合わせるには、不正確な結果を防ぐために慎重な考慮が必要です。よくある落とし穴は、結合時のデカルト積効果から発生し、合計が膨らむ原因となります。
問題: SUM() の結果が水増しされてしまう
ユーザーが、それぞれ異なるテーブルから合計を計算する 2 つのクエリを 1 つの結合クエリに統合しようとしました。
クエリ 1 (走行距離): 教師ごとにグループ化された、1 週間あたりの運転時間 (分単位) を合計します。
<code class="language-sql">SELECT last_name, first_name, ..., SUM(drive_time) AS MINUTES FROM bhds_mileage ... WHERE mil_date BETWEEN ... AND ... GROUP BY ...</code>
クエリ 2 (タイムカード): 教師ごとにグループ化された、1 週間あたりの合計時間を合計します。
<code class="language-sql">SELECT last_name, first_name, ..., SUM(tm_hours) AS total FROM bhds_timecard ... WHERE tm_date BETWEEN ... AND ... GROUP BY ...</code>
失敗した参加試行:
ユーザーがこれらのクエリを直接結合しようとした結果、合計が不正確になりました:
<code class="language-sql">SELECT last_name, first_name, ..., SUM(tm_hours) AS total, SUM(drive_time) AS MINUTES FROM bhds_timecard ... LEFT JOIN bhds_mileage ... ON ... WHERE ... GROUP BY ...</code>
問題は? SUM()
関数は結合後に適用され、結合されたテーブル間で複数の一致する行が存在する可能性があるため、合計の乗算が行われました。
解決策: 事前に集計されたサブクエリ
正しいアプローチには、結合する前にサブクエリの合計を事前に集計することが含まれます。
<code class="language-sql">SELECT last_name, first_name, ..., total, minutes FROM bhds_teachers ... LEFT JOIN ( -- Subquery 1: Mileage SUM SELECT teacher_id, SUM(drive_time) AS minutes, ... FROM bhds_mileage ... WHERE mil_date BETWEEN ... AND ... GROUP BY teacher_id ) AS m ON ... LEFT JOIN ( -- Subquery 2: Timecard SUM SELECT teacher_id, SUM(tm_hours) AS total, ... FROM bhds_timecard ... WHERE tm_date BETWEEN ... AND ... GROUP BY teacher_id ) AS t ON ...</code>
個別のサブクエリ内で SUM()
操作を実行することで、結合が行われる前に各テーブルのデータが正しく集計され、合計の乗算が防止され、正確な結果が得られるようにします。 teacher_id
(または同等のもの) は、正しい結合条件にとって重要です。
以上が複数のテーブルを結合すると MySQL SUM() の結果が正しくないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。