在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中文网其他相关文章!