【问题标题】:SELECT a column not in GROUP BY clause选择不在 GROUP BY 子句中的列
【发布时间】: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 子句,您的查询将按预期工作。

标签: mysql database


【解决方案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】:

只有那些年份和事件需要过滤,其中包含该年份的单个事件

  1. Inner Query 只会给你有一个事件的年份
  2. 外部查询将选择那些年的事件
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 stackoverflow.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';
      猜你喜欢
      • 1970-01-01
      • 2020-01-01
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      相关资源
      最近更新 更多