我有一张桌子看起来像这个叫“Makerar”的人
cname | wmname | avg
--------+-------------+------------------------
canada | zoro | 2.0000000000000000
spain | luffy | 1.00000000000000000000
spain | usopp | 5.0000000000000000
并且我要为每个CNAME选择最大平均数值。
SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname;
ERROR: column "makerar.wmname" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname;
所以我这样做
SELECT cname, wmname, MAX(avg) FROM makerar GROUP BY cname, wmname;
然而,这将不会给出预期的结果,并且下面显示了不正确的输出。
cname | wmname | max
--------+--------+------------------------
canada | zoro | 2.0000000000000000
spain | luffy | 1.00000000000000000000
spain | usopp | 5.0000000000000000
实际结果应该是
cname | wmname | max
--------+--------+------------------------
canada | zoro | 2.0000000000000000
spain | usopp | 5.0000000000000000
我如何解决这个问题?
注意:此表是根据以前的操作创建的视图。
是的,这是一个常见的聚合问题。在SQL3(1999)之前,所选字段必须出现在GROUP BY
子句[*]中。
要解决此问题,您必须在子查询中计算聚合,然后将其与自身连接,以获得需要显示的附加列:
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
;
cname | wmname | mx
--------+--------+------------------------
canada | zoro | 2.0000000000000000
spain | usopp | 5.0000000000000000
但您也可能使用窗口函数,这看起来更简单:
SELECT cname, wmname, MAX(avg) OVER (PARTITION BY cname) AS mx
FROM makerar
;
这个方法唯一的一点就是它会显示所有的记录(窗口函数不分组)。但它将在每一行中显示国家/地区的正确值(即CNAME
级别的最大值)max
,因此这取决于您:
cname | wmname | mx
--------+--------+------------------------
canada | zoro | 2.0000000000000000
spain | luffy | 5.0000000000000000
spain | usopp | 5.0000000000000000
显示与max值匹配的唯一(cname,wmname)
元组的解决方案可能不那么优雅,它是:
SELECT DISTINCT /* distinct here matters, because maybe there are various tuples for the same max value */
m.cname, m.wmname, t.avg AS mx
FROM (
SELECT cname, wmname, avg, ROW_NUMBER() OVER (PARTITION 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
;
cname | wmname | mx
--------+--------+------------------------
canada | zoro | 2.0000000000000000
spain | usopp | 5.0000000000000000
[*]:非常有趣的是,尽管规范允许选择非分组字段,但主要引擎似乎并不喜欢它。Oracle和SQLServer根本不允许这样做。默认情况下,Mysql允许它,但现在从5.7开始,管理员需要在服务器配置中手动启用此选项(only_full_group_by
)才能支持此功能...
试图在一个和中进行一个over(order by Id asc行之间的无界前行和当前行),我试图为每个值获得一个累加和。据我所知:
问题内容: 我在SO上找到了一些主题,但是仍然找不到适合我的查询的设置。 这是查询,在本地主机上运行得很好: 但是在Heroku上,我 遇到了-GROUP BY子句 上面的错误, 或者在聚合函数中使用 。 然后,我在某处读到,我应该指定表中的所有列,因此我尝试了以下操作: 但这在本地主机上不起作用,在Heroku上也不行… 什么是查询的正确配置? 问题答案: 我认为您正在尝试在同一列上进行汇总和分
演示:https://gcc.godbolt.org/z/c33gbqfqh 我在https://en.cppreference.com/w/cpp/language/aggregate_initialization中没有发现任何关于“析构函数”的提及。标准真的要求聚合字段的析构函数对聚合的每个潜在用户都可用吗?
问题内容: 简而言之,我有一个表格,其中除其他外,还包含一个用于时间戳记的列。我想获得具有最新(即最大价值)时间戳的行。目前,我正在这样做: 但是我宁愿做这样的事情: 但是,SQLite拒绝此查询: 该文件证实了这一行为(页面底部): 聚合函数只能在SELECT语句中使用。 我的问题是:是否可以编写查询以获取具有最大时间戳的行,而无需对select进行排序并将返回的行数限制为1?这似乎应该有可能,
是GCC和Clang中的bug,还是标准允许他们接受此代码?
问题内容: 我有此SQL语句,并且SQL Server给我以下错误: 除非聚合不在HAVING子句或选择列表中包含的子查询中,否则它可能不会出现在WHERE子句中。 在where子句中,我只想提取最旧的未付款帐单日期大于DelinquentDaysThreshhold(以天为单位)或PastDueAmount(计算值)大于DelinquentAmountThreshold的记录。 由于某些原因,S