2010-07-02 59 views
2

我有一个包含以下几列的用户表:SQL分组依据 - 选择两列

| 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_IDs的。

在此先感谢您的帮助!

回答

3

这里是一个否定的逻辑查询:

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

正是我在找的东西,非常感谢你,先生。 – pws5068 2010-07-02 02:13:55

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:

+0

曲子user_id'的'从GROUP BY,MySQL的只有与支持的SQLite在GROU隐藏列的遗漏(假设OP在运行查询时没有收到错误)。 – 2010-07-02 00:58:21

+0

@OMG Ponies:假设'GROUP_CONCAT()'是一个聚合(否则它没有多大意义),没有理由不能在其他RDBMS上工作(假设它或类似的东西存在)。 – 2010-07-02 01:03:58

+0

对不起,我应该指定,我正在使用MySql。我从来没有听说过Group_Concat,但查询起作用。我最终使用了David B的分离目的,但我也从中学到了一些东西!谢谢! – pws5068 2010-07-02 02:13:11

1
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) 
1

从理论上讲,你要的是这样的事情,但遗憾的是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