tsql分析查询

时间:2015-01-23 02:51:13

标签: sql sql-server performance tsql

我有事实和日期维度表。我需要编写一个查询,为每个日期成员返回其聚合函数(sum(amount))。但是这个聚合函数需要根据日期进行过滤。

FACT table: InvFactMain
Dim table: Dates

目前我有这个问题:

SELECT D.DATE
       ,(
        SELECT sum(inline.InventoryRetailAmount)
        FROM InvFactMain inline
        WHERE inline.DocumentDate >= DATEADD(day, - @x, D.DATE)
            AND inline.DocumentDate < dateadd(day, - @y, D.DATE)
        ) AS [RetailAmount]
FROM InvFactMain F
     JOIN Dates D ON D.Date_ID = F.DateId
GROUP BY D.DATE

我确信有更好更有效的方法来实现它。

•我正在使用SQL 2012,所以我可以使用分析函数作为LAG,LEAD等。

有什么想法吗?

4 个答案:

答案 0 :(得分:0)

如果我理解这必须做的正确,我认为这应该是正确的......

SELECT D.Date, q.s AS [Sum]
FROM Dates D
CROSS APPLY (
    SELECT SUM(F.InventoryRetailAmount) s
    FROM InvFactMain F
    WHERE F.Date_ID = D.DateID
          AND D.Date BETWEEN DATEADD(day, -@x, D.Date) AND DATEADD(day, -@y, D.Date)
) q

答案 1 :(得分:0)

这对你有帮助吗?

SELECT  D.Date ,
        SUM(inline.InventoryRetailAmount) AS amount
FROM    InvFactMain F
        INNER JOIN Dates D ON D.Date_ID = F.DateId
        INNER JOIN InvFactMain inv ON inv.DocumentDate >= DATEADD(DAY, -@x,
                                                              D.Date)
                                      AND inv.DocumentDate < DATEADD(DAY, -@y,
                                                              D.Date)
GROUP BY D.Date
HAVING  SUM(inline.InventoryRetailAmount) = YOUR_FILTER

答案 2 :(得分:0)

我相信你可以通过使用窗口功能来实现你的目标。我以冒险作品为例。

SELECT       d.FullDateAlternateKey
           ,f.SalesAmount
           ,TotalSales = sum(SalesAmount) OVER (PARTITION BY d.FullDateAlternateKey ORDER BY d.FullDateAlternateKey            )
           ,RunningTotalPerDay = sum(SalesAmount) OVER (PARTITION BY d.FullDateAlternateKey ORDER BY d.FullDateAlternateKey ROWS UNBOUNDED PRECEDING)
           ,RunningTotalLastTenDays = sum(SalesAmount) OVER (ORDER BY d.FullDateAlternateKey ROWS BETWEEN 9 PRECEDING AND CURRENT ROW)
FROM           [dbo].[DimDate] d
           JOIN [dbo].[FactInternetSales] f 
           ON d.DateKey = f.OrderDateKey

查询的输出:

+----------------------+-------------+------------+--------------------+-------------------------+
| FullDateAlternateKey | SalesAmount | TotalSales | RunningTotalPerDay | RunningTotalLastTenDays |
+----------------------+-------------+------------+--------------------+-------------------------+
| 2005-07-01           | 3578.27     | 14477.3382 | 3578.27            | 3578.27                 |
| 2005-07-01           | 3399.99     | 14477.3382 | 6978.26            | 6978.26                 |
| 2005-07-01           | 3399.99     | 14477.3382 | 10378.25           | 6799.98                 |
| 2005-07-01           | 699.0982    | 14477.3382 | 11077.3482         | 4099.0882               |
| 2005-07-01           | 3399.99     | 14477.3382 | 14477.3382         | 4099.0882               |
| 2005-07-02           | 3578.27     | 13931.52   | 3578.27            | 6978.26                 |
| 2005-07-02           | 3578.27     | 13931.52   | 7156.54            | 7156.54                 |
+----------------------+-------------+------------+--------------------+-------------------------+

答案 3 :(得分:0)

感谢您的回答。 我找到了一种非常简单的方法来实现它: (刚刚在连接谓词上添加了过滤器)

select d.date_id,sum(f.InventoryRetailAmount) from InvFactMain f inner join dates d
on f.DocumentDate >  dateadd(day,-@x,d.date)  and f.DocumentDate< dateadd(day,-@y,d.date)
group by d.Date_ID
order by d.Date_ID

完美无缺。