【问题标题】:SQL Group By - Select Both ColumnsSQL Group By - 选择两列
【发布时间】:2010-07-02 00:42:22
【问题描述】:

我有一个包含以下列的用户表:

| User_ID  (int) | Name (varchar) |   Age (int)  |  Experience_Level (int) |

我想创建一个 sql 查询来输出在年龄和经验的组合中不唯一的人的所有 ID。

到目前为止我的代码:

SELECT Count(*), User_ID FROM Users 
GROUP BY Age,Experience_Level
HAVING Count(*) > 1

显然这是不完整的,这会将非唯一用户分组,但不会告诉我他们所有的 User_ID。

提前感谢您的帮助!

【问题讨论】:

    标签: sql mysql group-by having


    【解决方案1】:

    这是一个否定逻辑查询:

    SELECT *
    FROM Users
    WHERE UserID not in
    (
    SELECT MIN(UserID)
    FROM Users
    GROUP BY Age, Experience_Level
    HAVING COUNT(*) = 1
    )
    

    【讨论】:

      【解决方案2】:

      由于您需要有关多个用户组的信息,您希望如何返回这些数据?在包含逗号分隔的 user_id 值列表的字符串中?

      您没有用您使用的 SQL 数据库品牌标记您的问题。

      如果你使用 MySQL 或 SQLite,你可以使用内置的GROUP_CONCAT() 函数:

      SELECT Count(*), GROUP_CONCAT(User_ID) AS User_List FROM Users 
      GROUP BY Age,Experience_Level
      HAVING Count(*) > 1
      

      默认情况下,GROUP_CONCAT() 使用逗号分隔值。如果您希望以其他方式格式化,请参阅手册。

      对于其他 SQL 供应商,还有其他解决方案。这个问题在 Stack Overflow 上出现过多次:

      【讨论】:

      • 由于 GROUP BY 中省略了user_id,只有 MySQL 和 SQLite 支持 group by 中的隐藏列(假设 OP 在运行查询时没有出错)。跨度>
      • @OMG Ponies:假设GROUP_CONCAT() 是一个聚合(否则它没有多大意义),它没有理由不能在其他 RDBMS 上工作(假设它,或类似的东西,存在)。
      • 对不起,我应该指定,我正在使用 MySql。我从未听说过 Group_Concat,但查询有效。我最终将大卫 B 的答案用于分离目的,但我也从中学到了一些东西!谢谢!
      • @Adam Robinson:我对 Bill 的评论是关于确定数据库供应商的 OP 查询。 GROUP_CONCAT 仅在 MySQL 和 SQLite 上 - 在 SO 上搜索逗号分隔的列表生成。
      【解决方案3】:
      SELECT t.User_ID, t.Age, t.Experience_Level
      FROM Users t INNER JOIN 
          (SELECT Age, Experience_Level
          FROM Users
          GROUP BY Age, Experience_Level
          HAVING Count(*) > 1) d ON t.Age = d.Age AND t.Experience_Level = d.Experience_Level
      

      测试脚本:

      create table Users (
      User_ID int,
      Name varchar(50),
      Age int,
      Experience_Level int
      )
      
      insert into Users (User_ID, Name, Age, Experience_Level) values (1, 'A', 33, 1)
      insert into Users (User_ID, Name, Age, Experience_Level) values (2, 'B', 37, 1)
      insert into Users (User_ID, Name, Age, Experience_Level) values (3, 'C', 33, 1)
      insert into Users (User_ID, Name, Age, Experience_Level) values (4, 'D', 35, 2)
      insert into Users (User_ID, Name, Age, Experience_Level) values (5, 'E', 33, 1)
      insert into Users (User_ID, Name, Age, Experience_Level) values (6, 'F', 35, 2)
      insert into Users (User_ID, Name, Age, Experience_Level) values (7, 'G', 18, 1)
      

      【讨论】:

        【解决方案4】:

        理论上,你想要的是这样的,但不幸的是 SQL Server 不允许:

        SELECT * FROM Users 
        WHERE (Age, Experience_Level) IN
        (
            SELECT Age, Experience_Level
            FROM Users  
            GROUP BY Age,Experience_Level 
            HAVING Count(*) > 1 
        )
        

        因此,您必须满足于加入子查询:

        SELECT Users.* FROM Users 
        INNER JOIN 
        (
            SELECT Age, Experience_Level
            FROM Users  
            GROUP BY Age,Experience_Level 
            HAVING Count(*) > 1 
        ) subq 
            ON Users.Age = subq.Age
            AND Users.Experience_Level = subq.Experience_Level
        

        【讨论】:

          猜你喜欢
          • 2021-01-15
          • 1970-01-01
          • 2015-03-29
          • 1970-01-01
          • 2012-08-13
          • 1970-01-01
          • 1970-01-01
          • 2011-09-02
          • 1970-01-01
          相关资源
          最近更新 更多