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)
有几种方法可以做到这一点。您可以使用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)
(注意:前面SUM在CASE语句上使用的示例不需要,因为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)
快速但肮脏的方法是将查询包装在另一个聚合中。
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)