如何在子查询之外的子查询中过滤日期

How to filter on date in subquery outside of subquery

我的 ETL 查询 return 是关于员工的一些信息,还有两个来自子查询的聚合列(ActualCountExpectedCount)。

我遇到的问题是 table 子查询左连接的更新独立于聚合信息。因此,当我递增地查询 运行 时,查询会发现 t1.ModifiedDate 尚未更新,并且即使计数记录已更新,也不会 return 新计数记录。

我写了这个查询,它 return 是增量加载所需的结果,但我现在的问题是,在初始加载期间,每个 ID 都有多个结果 returned,这违反了PK约束。这是由于我在子查询中添加了 t2.ModifiedDate 列,我需要根据它进行筛选。

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

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

当前查询:

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

您可以使用 exists().

而不是从子查询中携带 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
        )

Laughing Vergil 建议的 max(isr.ModifiedDate) 方法可能会更好。

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'