0

假设我有一个 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 中执行此操作,因此任何可能有用的特殊函数或命令都是公平的

4

1 回答 1

1

您可以使用COUNT()withOVER()来获得您所追求的:

;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

这使您可以保留完整的详细信息并返回聚合进行过滤。

于 2014-10-15T19:37:32.960 回答