假设我有一个Employee表和一个Department表。每个员工都有一个部门。
现在,假设我想看到所有部门 - 以及那些部门的员工 - ,只有1名员工。
假设我的数据库看起来像这样。
员工
EmployeeId | EmployeeName | DepartmentId
--------------------------------------------
1 | A Doe | 1
--------------------------------------------
2 | B Doe | 1
--------------------------------------------
3 | C Doe | 1
--------------------------------------------
4 | D Doe | 1
--------------------------------------------
5 | E Doe | 2
--------------------------------------------
系
DepartmentId | DepartmentName
------------------------------------------
1 | Sales
------------------------------------------
2 | HR
------------------------------------------
我想看到的是以下结果:
DepartmentName | EmployeeId | EmployeeName | EmployeeId_COUNT
------------------------------------------------------------------
HR | NULL | NULL | 1
------------------------------------------------------------------
HR | 5 | E Doe | 1
------------------------------------------------------------------
显然,这可以通过多个单独的查询来完成。
但是,是否有人知道使用单个查询解决此问题的方法?
我最初的想法是做一些简单的事情,比如这个
SELECT
d.DepartmentName 'Department'
, e.EmployeeId 'EmployeeId'
, e.EmployeeName
, COUNT(e.EmployeeId) 'EmployeeId_COUNT'
FROM Employee e
LEFT JOIN Department d ON d.DepartmentId = e.DepartmentId
GROUP BY GROUPING SETS (
( d.DepartmentName ),
( d.DepartmentName, e.EmployeeId, e.EmployeeName) )
HAVING COUNT(e.EmployeeId) IN (1)
但是这不起作用,因为每个不是分组行的行(以及一些分组的行)的EmployeeId计数为1。
因此,结果将如下所示:
DepartmentName | EmployeeId | EmployeeName | EmployeeId_COUNT
------------------------------------------------------------------
HR | NULL | NULL | 1
------------------------------------------------------------------
HR | 5 | E Doe | 1
------------------------------------------------------------------
Sales | 1 | A Doe | 1
------------------------------------------------------------------
Sales | 2 | B Doe | 1
------------------------------------------------------------------
Sales | 3 | C Doe | 1
------------------------------------------------------------------
Sales | 4 | D Doe | 1
------------------------------------------------------------------
这根本不是我想要的。
我理想的解决方案很简单(不需要复杂的内部查询,UNION或INTERSECT),并且很容易推广到类似的问题(SUM,MAX,MIN等以及更复杂查询中的其他列)。
我还应该注意我在T-SQL 2012中这样做,所以任何可能有用的特殊功能或命令都是合理的游戏。
答案 0 :(得分:1)
您可以COUNT()
与OVER()
一起使用,以获取您之后的信息:
;with cte AS (SELECT *,COUNT(*) OVER(PARTITION BY DepartmentID) AS Department_CT
FROM Employee)
SELECT *
FROM cte a
JOIN Department b
ON a.DepartmentID = b.DepartmentID
WHERE Department_CT = 1
这允许您保留完整的详细信息以及返回聚合以进行过滤。