如何在子查询

时间:2017-01-24 16:12:10

标签: sql-server tsql ssis etl

我的ETL查询返回有关员工的一些信息,并且还有两个来自子查询的聚合列(ActualCountExpectedCount)。

我遇到的问题是子查询左对齐的表是独立于聚合信息而更新的。因此,当我的查询以递增方式运行时,查询会看到t1.ModifiedDate没有更新,即使计数记录已更新,也不会返回新的计数记录。

我写了这个查询,它返回了增量加载的所需结果,但我现在的问题是在初始加载期间,每个ID都返回了多个结果,并且它违反了PK约束。这是因为我在子查询中添加了t2.ModifiedDate列,我需要对其进行过滤。

有没有办法获取t2.ModifiedDate并将其带到主查询而不会产生重复项?

期望的结果(我为此增量测试添加了一个结果):

enter image description here

当前查询:

SELECT  t1.EmployeeGoalID ,
        t1.EmployeeID ,
        t1.EmployeeMonthlyGoal ,
        t1.TargetMonth ,
        t1.TargetYear ,
        Actuals.BranchID ,
        Actuals.ActualCount ,
        CASE WHEN Actuals.ActualCount IS NULL THEN 0
             WHEN Actuals.ActualCount < t1.EmployeeMonthlyGoal
             THEN Actuals.ActualCount
             ELSE t1.EmployeeMonthlyGoal
        END AS ExpectedCount ,
        t1.CreateDate ,
        t1.ModifiedDate ,
        t1.Deleted
FROM    dbo.EmployeeGoal t1
        LEFT JOIN ( SELECT  COUNT(DISTINCT t2.InspectionSubmissionResultID) AS ActualCount ,
                            t2.BranchID ,
                            t3.EmployeeID ,
                            MONTH(DATEADD(hh, -5, t2.SubmissionDate)) AS ActualMonth ,
                            YEAR(DATEADD(hh, -5, t2.SubmissionDate)) AS ActualYear,
                            t2.ModifiedDate -- <<<<<This causes the problem
                    FROM    InspectionSubmissionResult t2
                            INNER JOIN dbo.InspectionSubmissionEmployee t3 ON t3.InspectionSubmissionResultID = t2.InspectionSubmissionResultID
                    WHERE   t3.InspectorType = 'INSP'
                    GROUP BY t2.BranchID ,
                            t3.EmployeeID ,
                            MONTH(DATEADD(hh, -5, t2.SubmissionDate)) ,
                            YEAR(DATEADD(hh, -5, t2.SubmissionDate)) ,
                            t2.ModifiedDate  -- <<<<This causes the problem
                  ) AS Actuals ON Actuals.EmployeeID = t1.EmployeeID
                                  AND t1.TargetMonth = Actuals.ActualMonth
                                  AND t1.TargetYear = Actuals.ActualYear
WHERE Actuals.ModifiedDate > '1/23/2017' OR t1.ModifiedDate > '1/23/2017'
-- I need this Actuals.ModifiedDate

1 个答案:

答案 0 :(得分:1)

您可以改为使用ModifiedDate子句而不是从子查询中携带where来使用它,而不是select eg.EmployeeGoalID , eg.EmployeeID , eg.EmployeeMonthlyGoal , eg.TargetMonth , eg.TargetYear , a.BranchID , a.ActualCount , ExpectedCount = case when a.ActualCount is null then 0 when a.ActualCount < eg.EmployeeMonthlyGoal then a.ActualCount else eg.EmployeeMonthlyGoal end , eg.CreateDate , eg.ModifiedDate , eg.Deleted from dbo.EmployeeGoal eg left join ( select ActualCount = count(distinct isr.InspectionSubmissionResultID) , isr.BranchID , ise.EmployeeID , ActualMonth = month(dateadd(hh, - 5, isr.SubmissionDate)) , ActualYear = year(dateadd(hh, - 5, isr.SubmissionDate)) --, isr.ModifiedDate -- <<<<<This causes the problem from dbo.InspectionSubmissionResult isr inner join dbo.InspectionSubmissionEmployee ise on ise.InspectionSubmissionResultID = isr.InspectionSubmissionResultID where ise.InspectorType = 'insp' group by isr.BranchID , ise.EmployeeID , month(dateadd(hh, - 5, isr.SubmissionDate)) , year(dateadd(hh, - 5, isr.SubmissionDate)) --, isr.ModifiedDate -- <<<<This causes the problem ) as a on a.EmployeeID = eg.EmployeeID and eg.TargetMonth = a.ActualMonth and eg.TargetYear = a.ActualYear where eg.ModifiedDate > '1/23/2017' -- or a.ModifiedDate > '1/23/2017' or exists ( select 1 from dbo.InspectionSubmissionResult isr inner join dbo.InspectionSubmissionEmployee ise on ise.InspectionSubmissionResultID = isr.InspectionSubmissionResultID where ise.EmployeeId = eg.EmployeeId and isr.ModifiedDate > '1/23/2017' and month(dateadd(hh, - 5, isr.SubmissionDate))=eg.TargetMonth and year(dateadd(hh, - 5, isr.SubmissionDate))=eg.TargetYear )

以下是您对更改的查询,以及一些重新格式化:

max(isr.ModifiedDate)

Laughing Vergil建议的select eg.EmployeeGoalID , eg.EmployeeID , eg.EmployeeMonthlyGoal , eg.TargetMonth , eg.TargetYear , a.BranchID , a.ActualCount , ExpectedCount = case when a.ActualCount is null then 0 when a.ActualCount < eg.EmployeeMonthlyGoal then a.ActualCount else eg.EmployeeMonthlyGoal end , eg.CreateDate , eg.ModifiedDate , eg.Deleted from dbo.EmployeeGoal eg left join ( select ActualCount = count(distinct isr.InspectionSubmissionResultID) , isr.BranchID , ise.EmployeeID , ActualMonth = month(dateadd(hh, - 5, isr.SubmissionDate)) , ActualYear = year(dateadd(hh, - 5, isr.SubmissionDate)) , ModifiedDate = max(isr.ModifiedDate) -- <<<<<This causes the problem from dbo.InspectionSubmissionResult isr inner join dbo.InspectionSubmissionEmployee ise on ise.InspectionSubmissionResultID = isr.InspectionSubmissionResultID where ise.InspectorType = 'insp' group by isr.BranchID , ise.EmployeeID , month(dateadd(hh, - 5, isr.SubmissionDate)) , year(dateadd(hh, - 5, isr.SubmissionDate)) --, isr.ModifiedDate -- <<<<This causes the problem ) as a on a.EmployeeID = eg.EmployeeID and eg.TargetMonth = a.ActualMonth and eg.TargetYear = a.ActualYear where eg.ModifiedDate > '1/23/2017' or a.ModifiedDate > '1/23/2017' 方法可能会更好。

Character to be escaped     Escape Sequence Remark
%                               %%      May not always be required in doublequoted strings, just try
[                               \[
]                               \]