从每个父母那里获取孩子的数量.SQL Server 2012

时间:2015-11-24 05:33:29

标签: sql sql-server

我有两个应该是相同的数据库。对于某些表,我需要比较和计算父母得到的子女数,并将其与相同的数据库进行比较。

我在下面用正确的方法来计算孩子的数量? 还有更好的方法吗?

将一些虚拟数据放在一个样本下面。"员工"带地址的表 比较每个员工的地址数量。

我想要的结果是我已经得到的,但我想再次想知道是否有更好的方法来做到这一点。

期望的结果:

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

2 个答案:

答案 0 :(得分:0)

我在加入CTE而不是FULL JOIN时使用LEFT JOIN来捕获两个表中缺少的Employees。在使用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)
;

答案 1 :(得分: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
相关问题