1

以下を照会するより短い方法があるかもしれないと感じています。

この構造は、複数のストアド プロシージャで繰り返されます。
テーブルのターゲット要素と DimDate ビューのCROSS JOIN間で、メジャーごとに 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

左外側結合を行うことができます。見た目は単純ではないかもしれませんが、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よりも常に効率的なUNIONALLを使用しています。UNIONの最初の部分がグループ化され(重複なし)、2番目の部分が最初の部分をチェックして重複がないことを確認するため、これを行うことができます。私が効率に疑問を呈する唯一の理由は、UNIONの最初の部分を2回実行する必要があるかもしれないからです。

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 に答える
1

より効率的かどうかは完全にはわかりませんが、クエリでGROUP BY/を 1 回だけ実行してみてください。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 に答える
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 に答える