如何使用GROUP BY和SELF JOIN?

时间:2011-10-05 11:22:54

标签: sql-server group-by self-join

我有一个人桌,同时容纳人和他的经理。
我正在使用SELF JOIN选择经理电子邮件,但我得到了很多重复。

http://imageshack.us/photo/my-images/3/withoutgroupby.png

如何将GROUP BY用于我的查询

SELECT              P.prs_id AS 'Employee_id', M.prs_id AS 'Manager_id', M.prs_email AS 'Manager_email'
FROM                qrd_prs_person AS P
LEFT OUTER JOIN     qrd_prs_person AS M  
ON                  P.prs_manager_number = M.prs_number
  

GROUP BY M.prs_id

如果我在查询结尾处将此行添加到按Manager_id分组,则会收到此错误

  

列'qrd_prs_person.prs_id'在选择列表中无效,因为   它不包含在聚合函数或GROUP BY中   子句。

5 个答案:

答案 0 :(得分:3)

我不太确定你想要达到什么目标?

如果您正在查询每个员工返回一行,并且两个可选列包含经理的信息,那么您的原始查询是正确的(没有分组依据)。这种关系是多对一的,你从每个“很多”的行开始,每行有一个(可选的)“一”,所以不需要分组。

然而,假设您的数据是正确的,并且prs_number实际上对每个员工都是唯一的。如果您有两个或更多经理共享prs_number,那么最终会有人拥有多个经理。

通过使这成为一个外部联接,你也会回来没有经理的人(即食物链的顶端:)),这是你的意图吗?

修改

如果您只想要返回管理员,那么您不能保留第一列(P.prs_id)并为每个经理获得一行。如果您想要管理一个或多个人的人员列表,这将解决问题:

SELECT              M.prs_id AS 'Manager_id', M.prs_email AS 'Manager_email'
FROM                qrd_prs_person AS P
INNER JOIN          qrd_prs_person AS M  
ON                  P.prs_manager_number = M.prs_number
GROUP BY            M.prs_id, M.prs_email

答案 1 :(得分:1)

为什么你要分组,因为我看不到Min,Max,Sum或任何需要分组的东西? 也许order by就足够了?无论如何,如果你GROUP BY,那么任何不是SUMmed或MINed等的列必须都会出现在GROUP BY子句中。

答案 2 :(得分:0)

select语句中的所有列都需要分组,或者需要具有聚合函数,您可以尝试添加MAX(qrd_prs_person.prs_id)并查看它是否有效。应该帮助你: - )

此外,您还需要逐个添加电子邮件ID部分,否则使用MAX() 您的查询应该是

SELECT  MAX(P.prs_id) AS 'Employee_id', 
        M.prs_id AS 'Manager_id', 
        M.prs_email AS 'Manager_email'
FROM                
    qrd_prs_person AS P
    LEFT OUTER JOIN     
        qrd_prs_person AS M  ONP.prs_manager_number = M.prs_number
GROUP BY 
    M.prs_id, M.prs_email

答案 3 :(得分:0)

如果您使用的是MySQL,它只会从该组中获取一个M.prs_id值。但是这些值在组内部可能会有所不同,因此仅选择一个随机的值并不合理。这就是SQL Server抱怨的原因。

我认为您误解了GROUP BY的工作原理。你究竟想用这个查询实现什么目标?

答案 4 :(得分:0)

问题在于,当您执行group by时,突然您在select子句中对P.prs_id AS 'Employee_id'的内容有很多可能的答案。 (对于经理的每个员工都有一个。)SQL Sever想知道你想要去哪里,所以它坚持要你提供一些方法将它的所有值总计为一个值。

您可能希望获得一定数量的员工,因此只需将其替换为COUNT(P.prs_id) AS 'Employee_count'

您还需要将M.prs_email添加到您的group by子句中。