ホームページ >データベース >mysql チュートリアル >SQL GROUP BY 句と ORDER BY 句の名前の競合を解決するにはどうすればよいですか?
SQL GROUP BY
と ORDER BY
句の名前の競合: 解決策
元のクエリでは、計算された CASE
式列とソース列 (attempt.result
) の間の名前の競合により、ハードウェア モデル、結果の種類、および大文字と小文字でデータをグループ化するときに問題が発生します。 これにより、同じタイプとケースの組み合わせに対して複数の行が作成されます。
解決策は、GROUP BY
句内でソース列名を直接使用しないようにすることです。 ここでは 2 つの効果的なアプローチを紹介します:
方法 1: CASE 式によって直接グループ化します:
attempt.result
でグループ化する代わりに、CASE
式自体でグループ化します。
<code class="language-sql">GROUP BY model.name, attempt.type, CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END</code>
これにより、CASE
ステートメントの計算結果に基づいてデータが直接グループ化され、曖昧さが排除されます。
方法 2: 列エイリアスを使用する:
CASE
式の出力列にエイリアスを割り当てます:
<code class="language-sql">SELECT ..., CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END AS result1 GROUP BY model.name, attempt.type, result1</code>
エイリアス result1
は計算列とソース列を明確に区別し、競合を解決します。 この場合、ORDER BY
は別名が付けられた列名 (result1
) を優先することに注意してください。
ベスト プラクティス: 位置参照
名前の競合を完全に回避するには、GROUP BY
句と ORDER BY
句内で位置参照を利用します。このアプローチでは、特に複雑なクエリにおいて、エラーが発生しにくくなり、クエリの可読性が向上します。 以下の例は、簡略化され書き直されたクエリ内でこの手法を示しています。
<code class="language-sql">SELECT m.name, a.type, CASE WHEN a.result = 0 THEN 0 ELSE 1 END AS result, CURRENT_DATE - 1 AS day, count(*) AS ct FROM attempt a JOIN prod_hw_id p USING (hard_id) JOIN model m USING (model_id) WHERE ts >= '2013-11-06 00:00:00' AND ts < CURRENT_DATE --Corrected the incomplete WHERE clause GROUP BY 1, 2, 3 -- Positional references for model.name, a.type, result ORDER BY 1, 2, 3 -- Positional references for model.name, a.type, result</code>
この改訂されたクエリはより簡潔になり、潜在的な名前の衝突を回避します。 WHERE
句が完全であることを常にチェックしてください。 オリジナルは不完全であったため、上記を修正しました。
以上がSQL GROUP BY 句と ORDER BY 句の名前の競合を解決するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。