SQL Server-CTE递归,在子';谁的数据?

SQL Server-CTE递归,在子';谁的数据?,sql,sql-server,Sql,Sql Server,这个问题延续了上一个已解决的问题(非常感谢弗拉基米尔·巴拉诺夫),可在此处访问: 数据结构与以前几乎相同,只是在EmOvertime中有另一个名为“AttdDate”的列来指示员工的出勤日期。下面是EmOvertime表中的数据示例 Table Name : EmOvertime EmpId AttdDate TotalOtReal 2 2016-05-09 2.00 2 2016-05-10 2.00

这个问题延续了上一个已解决的问题(非常感谢弗拉基米尔·巴拉诺夫),可在此处访问:

数据结构与以前几乎相同,只是在EmOvertime中有另一个名为“AttdDate”的列来指示员工的出勤日期。下面是EmOvertime表中的数据示例

Table Name : EmOvertime
EmpId    AttdDate     TotalOtReal    
2        2016-05-09   2.00          
2        2016-05-10   2.00        
2        2016-05-11   2.00       
2        2016-05-12   2.00        
3        2016-05-12   3.00 
来自CsOrganizationEmHisOrganization的数据与前面的问题相同。假设我想在2016年5月12日显示所有组织数据及其TotalHours值,查询如下:

WITH
CTE_OrgHours
AS
(
SELECT
    Org.OrgId
    ,Org.OrgParentId
    ,Org.OrgName
    ,ISNULL(Overtime.TotalOtReal, 0) AS SumHours
    ,Overtime.AttdDate
FROM
    CsOrganization AS Org
    LEFT JOIN EmHisOrganization AS Emp ON Emp.OrgId = Org.OrgID
    LEFT JOIN EmOvertime AS Overtime ON Overtime.EmpId = Emp.EmpId
GROUP BY
    Org.OrgId
    ,Org.OrgParentId
    ,Org.OrgName
    ,Overtime.TotalOtReal
    ,Overtime.AttdDate
)
,CTE_Recursive
AS
(
SELECT
     CTE_OrgHours.OrgId
    ,CTE_OrgHours.OrgParentId
    ,CTE_OrgHours.OrgName
    ,CTE_OrgHours.SumHours
    ,CTE_OrgHours.AttdDate
    ,1 AS Lvl
    ,CTE_OrgHours.OrgId AS StartOrgId
    ,CTE_OrgHours.OrgName AS StartOrgName
FROM CTE_OrgHours

UNION ALL

SELECT
     CTE_OrgHours.OrgId
    ,CTE_OrgHours.OrgParentId
    ,CTE_OrgHours.OrgName
    ,CTE_OrgHours.SumHours
    ,CTE_OrgHours.AttdDate
    ,CTE_Recursive.Lvl + 1 AS Lvl
    ,CTE_Recursive.StartOrgId
    ,CTE_Recursive.StartOrgName
FROM
    CTE_OrgHours
    INNER JOIN CTE_Recursive ON CTE_Recursive.OrgId = CTE_OrgHours.OrgParentId
)
SELECT
    StartOrgId
    ,StartOrgName
    ,SUM(SumHours) AS TotalHours
FROM CTE_Recursive
WHERE AttdDate = '2016-05-12'
GROUP BY
    StartOrgId
    ,StartOrgName
ORDER BY StartOrgId
但查询结果如下所示:

OrgId      OrgName       TotalHours    
1          X COMPANY     14.00
2          Administrator 14.00
3          Adm 1         12.00 
4          Adm 2         0.00
5          Adm 1_1       0.00   
Desired Output
OrgId      OrgName       TotalHours    
1          X COMPANY     5.00
2          Administrator 5.00
3          Adm 1         3.00 
4          Adm 2         0.00
5          Adm 1_1       0.00
而正确的答案应该是这样的:

OrgId      OrgName       TotalHours    
1          X COMPANY     14.00
2          Administrator 14.00
3          Adm 1         12.00 
4          Adm 2         0.00
5          Adm 1_1       0.00   
Desired Output
OrgId      OrgName       TotalHours    
1          X COMPANY     5.00
2          Administrator 5.00
3          Adm 1         3.00 
4          Adm 2         0.00
5          Adm 1_1       0.00
EmOvertime中,孩子的数据似乎是作为其父数据的数量循环的,它有4个相同的ID。因此,显示值12.00。如何解决这个问题


任何帮助都将不胜感激。

如果您对某个特定日期感兴趣,这很简单

看起来您需要将
WHERE
过滤器移动到查询的前面部分。进入
CTE\u OrgHours
CTE_OrgHours
应为每个组织返回一行相关小时的总和。所有筛选都应在此查询中进行。递归部分稍后希望在
CTE\u orghurs
中每个组织有一行

WITH
CTE_OrgHours
AS
(
    SELECT
        Org.OrgId
        ,Org.OrgParentId
        ,Org.OrgName
        ,ISNULL(SUM(Overtime.TotalOtReal), 0) AS SumHours
    FROM
        CsOrganization AS Org
        LEFT JOIN EmHisOrganization AS Emp ON Emp.OrgId = Org.OrgID
        LEFT JOIN EmOvertime AS Overtime
            ON  Overtime.EmpId = Emp.EmpId
            AND Overtime.AttdDate = '2016-05-12'
    GROUP BY
        Org.OrgId
        ,Org.OrgParentId
        ,Org.OrgName
)
,CTE_Recursive
AS
(
    SELECT
         CTE_OrgHours.OrgId
        ,CTE_OrgHours.OrgParentId
        ,CTE_OrgHours.OrgName
        ,CTE_OrgHours.SumHours
        ,1 AS Lvl
        ,CTE_OrgHours.OrgId AS StartOrgId
        ,CTE_OrgHours.OrgName AS StartOrgName
    FROM CTE_OrgHours

    UNION ALL

    SELECT
         CTE_OrgHours.OrgId
        ,CTE_OrgHours.OrgParentId
        ,CTE_OrgHours.OrgName
        ,CTE_OrgHours.SumHours
        ,CTE_Recursive.Lvl + 1 AS Lvl
        ,CTE_Recursive.StartOrgId
        ,CTE_Recursive.StartOrgName
    FROM
        CTE_OrgHours
        INNER JOIN CTE_Recursive ON CTE_Recursive.OrgId = CTE_OrgHours.OrgParentId
)
SELECT
    StartOrgId
    ,StartOrgName
    ,SUM(SumHours) AS TotalHours
FROM CTE_Recursive
GROUP BY
    StartOrgId
    ,StartOrgName
ORDER BY StartOrgId;

我之前的尝试确实是试图将WHERE子句从最终SELECT移到CTE_orghurs中,但没有成功。但后来我没有意识到,只有在ON子句中添加“AND加班。AttdDate='2016-05-12'”才起作用。再次感谢你,你真的帮了我大忙。将此标记为答案!