在SQL中,執行聚合操作(例如尋找最大值)時,用於聚合的欄位也必須出現在GROUP BY子句中。否則將導致錯誤:「列必須出現在GROUP BY子句中或用作聚合函數」。
假設您想要找出表中每個客戶名稱 (cname) 的最大平均值 (avg):
<code class="language-sql">SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname;</code>
此查詢將傳回錯誤,因為wmname未包含在GROUP BY子句中。要解決此問題,您可以簡單地按cname和wmname進行分組:
<code class="language-sql">SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname, wmname;</code>
但是,此方法不會產生顯示每個唯一cname的最大avg值的預期結果。相反,它將按cname和wmname分組,導致每個cname有多行。要修正此問題,請遵循以下方法之一:
<code class="language-sql">SELECT cname, MAX(avg) AS mx FROM makerar GROUP BY cname;</code>
<code class="language-sql">SELECT m.cname, m.wmname, t.mx FROM ( SELECT cname, MAX(avg) AS mx FROM makerar GROUP BY cname ) t JOIN makerar m ON m.cname = t.cname AND t.mx = m.avg;</code>
視窗函數可讓您在指定視窗內跨行執行計算。在這種情況下,您可以使用PARTITION BY子句按cname分組,並在每個分區中計算最大avg值:
<code class="language-sql">SELECT cname, wmname, MAX(avg) OVER (PARTITION BY cname) AS mx FROM makerar;</code>
此方法將顯示所有記錄,但它將正確顯示每行每個cname的最大avg值。
如果您只想顯示與最大avg值相符的唯一元組,可以使用以下方法:
<code class="language-sql">SELECT cname, wmname, avg, ROW_NUMBER() OVER (PARTITION BY cname ORDER BY avg DESC) AS rn FROM makerar;</code>
<code class="language-sql">SELECT DISTINCT /* distinct matters here */ m.cname, m.wmname, t.avg AS mx FROM ( SELECT cname, wmname, avg, ROW_NUMBER() OVER (PARTITION BY cname ORDER BY avg DESC) AS rn FROM makerar ) t JOIN makerar m ON m.cname = t.cname AND m.wmname = t.wmname AND t.rn = 1;</code>
此方法將傳回一個唯一元組列表,其中包含每個cname的最大avg值。 注意ORDER BY avg DESC
的加入,確保排名是根據avg
降序排列的。
以上是如何解決SQL「列必須出現在GROUP BY子句中」錯誤?的詳細內容。更多資訊請關注PHP中文網其他相關文章!