[英]Get count of children from each parent.SQL Server 2012
我有2個應該相同的數據庫。 對於某些表,我需要比較並計算父母有多少個孩子,並將其與相同的數據庫進行比較。
我在獲得孩子人數的正確方法下面做了什么? 有沒有更好的辦法?
將下面的示例與一些虛設數據放在一起。帶有地址的“雇員”表比較每個雇員有多少地址。
期望的結果是我已經得到的,但是我再次想知道是否有更好的方法可以做到這一點。
所需結果:
EmployeeId TotalAddressesA TotalAddressesB
1 4 1
2 2 5
設定:
IF OBJECT_ID('tempdb..#EmployeeDBA') IS NOT NULL DROP TABLE #EmployeeDBA
IF OBJECT_ID('tempdb..#EmployeeDBAddressA') IS NOT NULL DROP TABLE #EmployeeDBAddressA
IF OBJECT_ID('tempdb..#EmployeeDBB') IS NOT NULL DROP TABLE #EmployeeDBB
IF OBJECT_ID('tempdb..#EmployeeDBAddressB') IS NOT NULL DROP TABLE #EmployeeDBAddressB
CREATE TABLE #EmployeeDBA
( [EmployeeId] [int] NOT NULL,
[Name] [varchar](50) NULL,
[Surname] [varchar](50) NULL
)
CREATE TABLE #EmployeeDBB
( [EmployeeId] [int] NOT NULL,
[Name] [varchar](50) NULL,
[Surname] [varchar](50) NULL
)
CREATE TABLE #EmployeeDBAddressA
( [EmployeeAddressId] [int] NOT NULL,
[EmployeeId][int] NOT NULL,
[Addresss] [varchar](50) NULL,
)
CREATE TABLE #EmployeeDBAddressB
( [EmployeeAddressId] [int] NOT NULL,
[EmployeeId][int] NOT NULL,
[Addresss] [varchar](50) NULL,
)
INSERT #EmployeeDBA (EmployeeId,Name,Surname)
VALUES(1,'Jo','Bloggs'),(2,'Mark','Smith')
INSERT #EmployeeDBB (EmployeeId,Name,Surname)
VALUES(1,'Jo','Bloggs'),(2,'Mark','Smith')
INSERT #EmployeeDBAddressA(EmployeeAddressId,EmployeeId,Addresss)
VALUES(1,1,'Address1ForEmployee1'),
(2,1,'Address2ForEmployee1'),
(3,1,'Address3ForEmployee1'),
(4,1,'Address4ForEmployee1'),
(5,2,'Address1ForEmployee2'),
(6,2,'Address2ForEmployee2')
INSERT #EmployeeDBAddressB(EmployeeAddressId,EmployeeId,Addresss)
VALUES(1,1,'Address1ForEmployee1'),
(2,2,'Address1ForEmployee2'),
(3,2,'Address2ForEmployee2'),
(4,2,'Address3ForEmployee2'),
(5,2,'Address4ForEmployee2'),
(6,2,'Address5ForEmployee2')
--BELOW IS WHAT I AM QUERYING IF IT'S BEST WAY TO FIND COUNT OF CHILDREN FOR EACH PARENT.
;WITH CTEA
AS ( SELECT A.EmployeeId,
TotalCountA = (
SELECT COUNT(EmployeeId)
FROM #EmployeeDBAddressA b
WHERE b.EmployeeId = a.EmployeeId)
FROM #EmployeeDBA A
GROUP BY A.EmployeeId ),
CTEB
AS (SELECT A.EmployeeId,
TotalCountB = (
SELECT COUNT(EmployeeId)
FROM #EmployeeDBAddressB b
WHERE b.EmployeeId = a.EmployeeId)
FROM #EmployeeDBB A
GROUP BY A.EmployeeId )
--is this the way to compare totals betwen 2 tables
SELECT A.EmployeeId,A.TotalCountA,B.TotalCountB
FROM CTEA A
LEFT JOIN CTEB B ON A.EmployeeId = B.EmployeeId
WHERE ISNULL(A.TotalCountA, 0) <> ISNULL(B.TotalCountB, 0);
DROP TABLE #EmployeeDBA
DROP TABLE #EmployeeDBAddressA
DROP TABLE #EmployeeDBB
DROP TABLE #EmployeeDBAddressB
加入CTE時,我會使用FULL JOIN
而不是LEFT JOIN
來捕獲兩個表中丟失的雇員。 在具有LEFT JOIN
當前變體中,如果EmployeeDBA
沒有行,但是EmployeeDBB
有行,則即使表不同,查詢也會返回空結果集。
在CTE中,我將聯接兩個表,而不是在子查詢中計算COUNT
。 不過,優化程序可能會生成相同的計划。
WITH
CTEA
AS
(
SELECT
Emp.EmployeeId
,COUNT(Addr.EmployeeId) AS TotalCountA
FROM
#EmployeeDBA AS Emp
LEFT JOIN #EmployeeDBAddressA AS Addr ON Addr.EmployeeId = Emp.EmployeeId
-- LEFT JOIN for those Employees that don't have addresses
GROUP BY Emp.EmployeeId
)
,CTEB
AS
(
SELECT
Emp.EmployeeId
,COUNT(Addr.EmployeeId) AS TotalCountA
FROM
#EmployeeDBB AS Emp
LEFT JOIN #EmployeeDBAddressB AS Addr ON Addr.EmployeeId = Emp.EmployeeId
-- LEFT JOIN for those Employees that don't have addresses
GROUP BY Emp.EmployeeId
)
SELECT
COALESCE(CTEA.EmployeeId, CTEB.EmployeeId) AS EmployeeId
,CTEA.TotalCountA
,CTEB.TotalCountB
FROM
CTEA
FULL JOIN CTEB ON CTEA.EmployeeId = CTEB.EmployeeId
-- FULL JOIN to catch missing Employees in both tables
WHERE
ISNULL(CTEA.TotalCountA, 0) <> ISNULL(CTEB.TotalCountB, 0)
;
您可以嘗試以下代碼:
SELECT * FROM (
SELECT EmployeeId
FROM #EmployeeDBA
UNION
SELECT EmployeeId
FROM #EmployeeDBB) AS C
CROSS APPLY (
SELECT COUNT(*) AS TotalCountA
FROM #EmployeeDBAddressA WHERE EmployeeId = C.EmployeeId
) AS A
CROSS APPLY (
SELECT COUNT(*) AS TotalCountB
FROM #EmployeeDBAddressB WHERE EmployeeId = C.EmployeeId
) AS B
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.