选择不在 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 C2014 D 行。 我尝试在Year 上执行GROUP BY,但这不会让我选择Event 列。 2011 年和 2013 年有 2 个事件,因此这些事件不应出现在结果中。

请帮忙。

编辑:我可以编写一个嵌套查询来获取只有 count(Year) = 1GROUP 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 子句中[关闭]

在 SQL 中选择不在 Group By 中的列

选择列表中的列“X”无效,因为它既不包含在聚合函数中,也不包含在 GROUP BY 子句中

选择列表中的列……无效,因为该列没有包含在聚合函数或 GROUP BY 子句中