如何编写包含不在GROUP BY子句中的列的标准SQL GROUP BY

时间:2011-03-06 04:01:28

标签: sql sql-server

假设我有一个名为Customer的表,定义如下:

Id       Name       DepartmentId    Hired
1        X          101             2001/01/01
2        Y          102             2002/01/01
3        Z          102             2003/01/01

我想检索每个部门上次招聘的日期。

显然我会这样做

SELECT c.DepartmentId, MAX(c.Hired)
  FROM Customer c
 GROUP BY c.DepartmentId

返回:

101      2001/01/01
102      2003/01/01

但是,如果我想要归还被雇佣人员的名字该怎么办?即我想要这个结果集:

101      2001/01/01       X
102      2003/01/01       Z

请注意,以下内容不起作用,因为它会返回三行而不是我正在寻找的两行:

SELECT c.DepartmentId, c.Name, MAX(c.Hired)
  FROM Customer c
 GROUP BY c.DepartmentId

我不记得看到一个实现此目的的查询。

注意:加入Hired字段不可接受,因为这不能保证准确。

4 个答案:

答案 0 :(得分:3)

子选择可以完成这项工作,并将处理同一天在同一部门雇用多个人的情况:

SELECT c.DepartmentId, c.Name, c.Hired from Customer c,
(SELECT DepartmentId, MAX(Hired) as MaxHired
  FROM Customer
 GROUP BY DepartmentId) as sub
WHERE c.DepartmentId = sub.DepartmentId AND c.Hired = sub.MaxHired

答案 1 :(得分:0)

标准版Sql:

select * 
from Customer C

where exists
(
  -- Linq to Sql put NULL instead ;-) 
  -- In fact, you can even put 1/0 here and would not cause division by zero error
  -- An RDBMS do not parse the select clause of correlated subquery
  SELECT NULL 

  FROM Customer 

  where c.DepartmentId = DepartmentId

  GROUP BY DepartmentId

  having c.Hired = MAX(Hired)
) 

如果Sql Server碰巧支持元组测试,那么这是最简单的:

select * 
from Customer 
where  (DepartmentId, Hired) in 

(select DepartmentId, MAX(Hired)
 from Customer 
 group by DepartmentId)

答案 2 :(得分:0)

SELECT a.*
FROM Customer AS a
JOIN
(SELECT DepartmentId, MAX(Hired) AS Hired
FROM Customer GROUP BY DepartmentId) AS b
USING (DepartmentId,Hired);

答案 3 :(得分:-1)

SELECT c.DepartmentId,c.Name,c.Hired 
FROM Customer c 
GROUP BY c.DepartmentId 
ORDER BY c.Hired DESC