1

我觉得可能有一种更短的方式来查询以下内容。

这种结构在几个存储过程中重复出现。
CROSS JOIN在表格的目标元素和 DimDate 视图之间执行一个 - 每个度量都为 0。然后UNION将结果与实际结果。然后在外部查询中,如果出现重复,它会全部聚合。

有没有更有效的方法来解决这个问题?

SELECT Name,
       DateKey,
       Measure1 = SUM(Measure1),
       Measure2 = SUM(Measure2)
FROM (
    SELECT  Name,
        DateKey,
        Measure1 = SUM(Measure1),
        Measure2 = SUM(Measure2)
    FROM    WH.dbo.tb_r12028dxi_Data
    GROUP BY SearchName,
        DateKey
    UNION 
    SELECT  Name,   
        d.DateKey,
        0,
        0
    FROM    WH.dbo.vw_DimDate d
        CROSS JOIN
        WH.dbo.tb_r12028dxi_Data a  
    WHERE   d.DayMarker >= CONVERT(DATETIME,CONVERT(CHAR(6),DATEADD(MM,-24,GETDATE()),112) + '01',112)
    GROUP BY a.Name,    
        d.DateKey
    ) x
GROUP BY Name,
    DateKey
4

4 回答 4

1

不完全确定它是否更有效,但您可以尝试在查询中只执行GROUP BY/SUM一次。

SELECT Name,
       DateKey,
       Measure1 = SUM(Measure1),
       Measure2 = SUM(Measure2)
FROM (
    SELECT  SearchName AS Name,
            DateKey,
            Measure1,
            Measure2
    FROM    WH.dbo.tb_r12028dxi_Data
    UNION 
    SELECT DISTINCT
            Name,   
            d.DateKey,
            0,
            0
    FROM    WH.dbo.vw_DimDate d
            CROSS JOIN WH.dbo.tb_r12028dxi_Data a  
    WHERE   d.DayMarker >= CONVERT(DATETIME,CONVERT(CHAR(6),DATEADD(MM,-24,GETDATE()),112) + '01',112)
    ) x
GROUP BY Name,
         DateKey
于 2013-03-20T15:57:55.527 回答
1

你可以做一个左外连接。它可能看起来并不简单,但它比 UNION 更容易评估数据库。

SELECT x.Name,
       x.DateKey,
       Measure1 = SUM(sum_table.Measure1),
       Measure2 = SUM(sum_table.Measure2)
FROM (SELECT distinct Name, d.DateKey
      FROM    WH.dbo.vw_DimDate d, WH.dbo.tb_r12028dxi_Data a  
      WHERE   d.DayMarker >= CONVERT(DATETIME,CONVERT(CHAR(6),DATEADD(MM,-24,GETDATE()),112) + '01',112)) x
  LEFT OUTER JOIN WH.dbo.tb_r12028dxi_Data sum_table
    ON x.Name = sum_table.Name AND x.DateKey = sum_table.DateKey
GROUP BY x.Name, x.DateKey

请注意,这假设您在 WH.dbo.tb_r12028dxi_Data 中需要的每个值都将在交叉连接中。否则,您需要完全外连接而不是左外连接。

于 2013-03-20T16:13:32.663 回答
1

我不确定我是否完全正确,因为我没有可以使用的结构,但这可能更有效。它使用的 UNION ALL 总是比 UNION 更有效。它能够做到这一点是因为 UNION 的第一部分被分组(没有重复),第二部分正在检查第一部分以确保它没有任何重复。我质疑效率的唯一原因是因为 UNION 的第一部分可能必须运行两次。

WITH DataResults (
SELECT  Name,
    DateKey,
    Measure1 = SUM(Measure1),
    Measure2 = SUM(Measure2) 
FROM    WH.dbo.tb_r12028dxi_Data
GROUP BY SearchName,
    DateKey
    )
SELECT * FROM DataResults
UNION ALL 
SELECT DISTINCT Name,   
    d.DateKey,
    0,
    0
FROM    WH.dbo.vw_DimDate d
CROSS JOIN WH.dbo.tb_r12028dxi_Data a  
WHERE   d.DayMarker >= CONVERT(DATETIME,CONVERT(CHAR(6),DATEADD(MM,-24,GETDATE()),112) + '01',112)
  -- Check for existence within the upper part o fthe union.
  AND NOT EXISTS (SELECT 1 FROM DataResults 
            WHERE a.Name = DataResults.Name -- I'm making an assumption here that name is in tb_r12028dxi_Data.  You didn't say.
              AND d.DateKey = DataResults.DateKey )
GROUP BY a.Name,    
    d.DateKey
于 2013-03-20T16:14:12.587 回答
0

pswg 方法的一种变体——我认为这可能更有效:

SELECT Name,
       DateKey,
       Measure1 = SUM(Measure1),
       Measure2 = SUM(Measure2)
FROM (SELECT SearchName AS Name,
             DateKey,
             Measure1,
             Measure2
      FROM   WH.dbo.tb_r12028dxi_Data
      UNION 
      SELECT Name,   
             d.DateKey,
             0,
             0
      FROM   WH.dbo.vw_DimDate d
      CROSS JOIN (SELECT DISTINCT Name FROM WH.dbo.tb_r12028dxi_Data) a  
      WHERE d.DayMarker >= CONVERT(DATETIME,CONVERT(CHAR(6),DATEADD(MM,-24,GETDATE()),112) + '01',112)
     ) x
GROUP BY Name, DateKey
于 2013-03-20T17:15:48.583 回答