选择不在 GROUP BY 子句中的列
Posted
技术标签:
【中文标题】选择不在 GROUP BY 子句中的列【英文标题】:SELECT a column not in GROUP BY clause 【发布时间】:2019-11-11 07:57:15 【问题描述】:我正在尝试编写一个查询,该查询将仅选择具有事件的行,这些事件是当年唯一的事件。
例如:
Year Event
2011 A
2011 B
2012 C
2013 B
2013 D
2014 D
所以,我想在结果中获得 2012 C
和 2014 D
行。
我尝试在Year
上执行GROUP BY
,但这不会让我选择Event
列。
2011 年和 2013 年有 2 个事件,因此这些事件不应出现在结果中。
请帮忙。
编辑:我可以编写一个嵌套查询来获取只有 count(Year) = 1
和 GROUP BY Year
的行,但我无法在外部查询中选择 Event
列
SELECT Year, Event from table where Year in (SELECT Year from table GROUP BY Year Having count(*) = 1) as count;
【问题讨论】:
删除 as 子句,您的查询将按预期工作。 【参考方案1】:你在查询中有一个小错误,在have子句中使用的count(*)
也应该在select子句中
SELECT Year, Event from table where Year in (
SELECT Year from (
SELECT Year,count(*) from table GROUP BY Year Having count(*) = 1)temp
);
【讨论】:
内部查询返回2列,与Year Mismatch列比较会出现错误【参考方案2】:只有那些年份和事件需要过滤,其中包含该年份的单个事件
-
Inner Query 只会给你有一个事件的年份
外部查询将选择那些年的事件
SELECT Year, Event from table where Year in
(SELECT Year from table GROUP BY Year Having count(*) = 1);
【讨论】:
【参考方案3】:SELECT Year, Event
FROM table
WHERE Year in (SELECT Year
FROM table
GROUP BY Year
HAVING count(*) = 1);
【讨论】:
你能解释为什么当它与发布的查询大致相同时它会起作用吗?【参考方案4】:好问题,
您甚至不需要子查询来获得所需的输出。将所有事件名称串联成一个字符串,然后在字符串中搜索逗号,
,如果找到逗号,
,则表示今年有多个事件,否则只有一个。
SELECT Year, GROUP_CONCAT(Event) AS Event FROM Events GROUP BY (year) having
INSTR(Event, ",") = 0;
【讨论】:
【参考方案5】:不需要使用子查询或嵌套查询。您可以简单地 GROUP By Year
字段并使用 HAVING COUNT(Year)=1
查找所需的行。因此,适用的查询将是:
SELECT Year, Event
FROM table_name
GROUP BY Year
HAVING COUNT(Year)=1
您可以在以下位置找到可执行的解决方案示例:
http://sqlfiddle.com/#!9/b47044/11
逻辑:
当您按Year
分组时,它会聚合同一年份的所有行。因此,2011
的计数将是 2
。
您可以通过运行来检查:
SELECT Year, Event, COUNT(Year) as event_count
FROM table_name
GROUP BY Year
你可以在执行中看到这个中间步骤,在:http://sqlfiddle.com/#!9/b47044/10
上述解决方案仅适用于 MySQL 版本
对于 5.7 及更高版本,默认启用 ONLY_FULL_GROUP_BY SQL 模式,因此这将失败。您可以更新此模式(请参阅 SELECT list is not in GROUP BY clause and contains nonaggregated column .... incompatible with sql_mode=only_full_group_by 下的答案),或者您可以使用 ANY_VALUE()
函数来引用非聚合列,因此在 mysql 5.7 及更高版本中可以使用的更新查询是:
SELECT Year, ANY_VALUE(Event)
FROM table_name
GROUP BY Year
HAVING COUNT(Year)=1;
您可以在以下位置找到可执行示例:https://paiza.io/projects/e/tU-7cUoy3hQUk2A7tFfVJg
参考:https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/miscellaneous-functions.html#function_any-value
【讨论】:
不错,我用这个SELECT Year, GROUP_CONCAT(Event) AS Event FROM Events GROUP BY (year) having INSTR(Event, ",") = 0;
,但你的似乎更具可读性
我试过这个,但这不起作用。不知道为什么。 ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'test.Events.Event' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
你使用的是哪个版本的 MySQL @FayazAhmed
@FayazAhmed 我假设您使用的是 MySQL 5.7 或更高版本。检查发现新版本可能不支持此查询。默认情况下ONLY_FULL_GROUP_BY
SQL 模式已启用。 Ref: docs.oracle.com/cd/E17952_01/mysql-5.7-en/… 简而言之,这是 MySQL ***.com/a/41887627/749232
谢谢。进行以下设置后即可使用。 mysql> set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'; mysql> set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
以上是关于选择不在 GROUP BY 子句中的列的主要内容,如果未能解决你的问题,请参考以下文章
我们如何在具有GROUP BY子句的查询中选择非聚合列,而GROUP BY子句在功能上不依赖于GROUP BY子句中的列?
选择列表中的列无效,因为该列没有包含在聚合函数或 GROUP BY 子句中
SQL:选择列表中的列无效,因为它不包含在聚合函数或 GROUP BY 子句中[关闭]