我有事实和日期维度表。我需要编写一个查询,为每个日期成员返回其聚合函数(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等。
有什么想法吗?
答案 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
完美无缺。