1

这是数据:

SELECT X.*
INTO   #X
FROM   (
       VALUES
       ('A',CAST('01 Feb 2013' AS DATETIME)),
       ('B','01 Mar 2013'),
       ('C','01 Sep 2013')
       ) X(Player,Mth)

我们的仓库里有一张非常标准的工厂DimDate桌子。

如果我执行以下操作来查找天数,它可以正常工作:

SELECT Player,Mth,
    numDays_mth = COUNT(XXX.DateKey),
FROM #X A
    CROSS APPLY 
    (
    SELECT DateKey 
    FROM WHData.dbo.vw_DimDate DT 
    WHERE DT.DayMarker >= A.Mth 
        AND DT.DayMarker < DATEADD(MONTH, 1, A.Mth)
    ) XXX

同样对于上个月的天数,一切正常:

SELECT Player,Mth,
    numDays_prevMth = COUNT(YYY.DateKey)     
FROM #X A
    CROSS APPLY 
    (
    SELECT DateKey 
    FROM WHData.dbo.vw_DimDate DTT 
    WHERE DTT.DayMarker >= DATEADD(MONTH, -1, A.Mth) 
    AND DTT.DayMarker < A.Mth
    ) YYY

如果我将两者结合起来,就会出现问题:

SELECT Player,Mth,
    numDays_mth = COUNT(XXX.DateKey),
    numDays_prevMth = COUNT(YYY.DateKey)    
FROM #X A
     CROSS APPLY 
     (
     SELECT DateKey 
     FROM WHData.dbo.vw_DimDate DT 
     WHERE DT.DayMarker >= A.Mth 
         AND DT.DayMarker < DATEADD(MONTH, 1, A.Mth)
     ) XXX
    CROSS APPLY 
    (
    SELECT DateKey 
    FROM WHData.dbo.vw_DimDate DTT 
    WHERE DTT.DayMarker >= DATEADD(MONTH, -1, A.Mth) 
    AND DTT.DayMarker < A.Mth
    ) YYY

我意识到还有很多其他方法可以获得这些天数,但我试图APPLY尽可能多地了解操作员的工作方式。

如何继续使用APPLY两次并停止重复数据?


笔记

将子句更改SELECT为以下内容适用于这个简单的示例,但会对生产脚本的性能产生巨大影响:

SELECT Player,Mth,
    numDays_mth = COUNT(DISTINCT XXX.DateKey),
    numDays_prevMth = COUNT(DISTINCT YYY.DateKey)   
4

1 回答 1

2

我会将COUNTs 移动到内部,CROSS APPLY以便每个输入行只为左侧的每个输入行产生一行输出。这样您就可以避免创建额外的行来充当第二个(或后续)的输入APPLY

SELECT Player,Mth,
    numDays_mth = XXX.Cnt,
    numDays_prevMth = YYY.Cnt   
FROM #X A
     CROSS APPLY 
     (
     SELECT COUNT(DateKey) 
     FROM WHData.dbo.vw_DimDate DT 
     WHERE DT.DayMarker >= A.Mth 
         AND DT.DayMarker < DATEADD(MONTH, 1, A.Mth)
     ) XXX (Cnt)
    CROSS APPLY 
    (
    SELECT COUNT(DateKey)
    FROM WHData.dbo.vw_DimDate DTT 
    WHERE DTT.DayMarker >= DATEADD(MONTH, -1, A.Mth) 
    AND DTT.DayMarker < A.Mth
    ) YYY (Cnt)
于 2013-10-28T13:52:00.887 回答