为 EmpName 返回一行

Bel*_*igh 5 sql-server t-sql sql-server-2008-r2

我的表中可能有也可能没有相同的员工姓名。问题是我无法知道 Table1 是否会包含更多名称,或者 Table2 是否会包含更多名称,所以我认为联合可以解决这个问题。但是,正如您在下面的语法中看到的那样,它会生成“C”的行,因为它存在于两个表中。这是我想要的输出

empName | TotalSW | TotalSNT  
--------+---------+---------
A       |       1 |       0
B       |       1 |       0
C       |       1 |       1
x       |       0 |       1
z       |       0 |       1
Run Code Online (Sandbox Code Playgroud)

使用下面的 DDL 如何编写查询以生成此输出?

Create Table #Test1
(empName varchar(100), swas varchar(100))

Create Table #Test2
(empName varchar(100), swont varchar(100))

Insert Into #Test1 (empName, swas) VALUES
('A', 'res1'), ('B', 'tim1'), ('C', 'run34')

Insert Into #Test2 (empName, swont) VALUES
('C', 'er12'), ('z', 'nn12'), ('x', '23rw')


Select empName, TotalSW = COUNT(swas), TotalSNT = ''
FROM #Test1
GROUP BY empName
Union 
Select empName, TotalSW = '', TotalSNT = Count(swont)
FROM #Test2
GROUP BY empName
Run Code Online (Sandbox Code Playgroud)

Dav*_*ett 7

有几种方法可以做到这一点。您可以使用FULL OUTER JOIN将提取数据的 a :

SELECT ISNULL(#Test1.empName, #Test2.empName)
     , TotalSW  = COUNT(#Test1.empName)
     , TotalSNT = COUNT(#Test2.empName)
FROM #Test1 
FULL OUTER JOIN #Test2 ON #Test2.empName = #Test1.EmpName
GROUP BY ISNULL(#Test1.empName, #Test2.empName)
Run Code Online (Sandbox Code Playgroud)

(注意:前面SUMCASE语句上使用的示例不需要,因为COUNT它不计算NULL额外的 jiggery-pokery 试图做的值)

或保留该UNION方法(根据查询的其余部分,在更复杂的示例中可能或多或少有效):

SELECT empName, TotalSW = SUM(TotalSW), SUM(TotalSNT)
FROM   (
        SELECT empName, TotalSW = 1, TotalSNT = 0
        FROM #Test1
        UNION ALL
        SELECT empName, TotalSW = 0, TotalSNT = 1
        FROM #Test2
        ) AS sq
GROUP BY empName
Run Code Online (Sandbox Code Playgroud)

请注意使用UNION ALLnot just UNION- 否则,如果员工在一个表中存在多次,它将过滤掉重复项。UNION ALL通常也更有效,因为它可能避免额外的排序操作,因此除非您需要重复删除,否则您应该使用它而不是普通的UNION

或者,如果您发现 CTE 语法比子查询更具可读性(它通常出现在更复杂的示例中,尽管在这里 IMO 没有区别):

WITH Emps AS (
        SELECT empName, TotalSW = 1, TotalSNT = 0
        FROM #Test1
        UNION ALL
        SELECT empName, TotalSW = 0, TotalSNT = 1
        FROM #Test2
        )
SELECT empName, TotalSW = SUM(TotalSW), SUM(TotalSNT)
FROM   Emps
GROUP BY empName
Run Code Online (Sandbox Code Playgroud)


Eri*_*ing 4

快速但肮脏的方法是将查询包装在另一个聚合中。

SELECT   x.empName, SUM(x.TotalSW), SUM(x.TotalSNT)
FROM     (
             SELECT   empName, COUNT(swas) AS TotalSW, 0 AS TotalSNT
             FROM     #Test1
             GROUP BY empName
             UNION ALL
             SELECT   empName, 0 AS TotalSW, COUNT(swont) AS TotalSNT
             FROM     #Test2
             GROUP BY empName ) AS x
GROUP BY x.empName;
Run Code Online (Sandbox Code Playgroud)