我希望有一个查询累加在一个列上,但它需要每个星期一重新启动但看起来不可能用窗口函数来实现 这是我的代码:
WITH t (fecha, nombre_dia, distribuidor, monto)as (
SELECT CAST(t.fecha AS DATE)fecha
, CASE WHEN datename(dw,t.fecha)='Monday' then 1 else 2 end nombre_dia
,d.NombreDistribuidor distribuidor
,sum(tr.Monto)monto
from HechosTransferencia tr inner join DimensionTiempo t on tr.DimensionTiempoId=t.DimensionTiempoId
inner join DimensionDistribuidor d on d.DimensionDistribuidorId=tr.DimensionDistribuidorId
WHERE (t.Fecha BETWEEN DATEADD(MONTH, DATEDIFF(MONTH, - 2, GETDATE()) - 2, 0) AND GETDATE())
group by CAST(t.fecha AS DATE)
, CASE WHEN datename(dw,t.fecha)='Monday' then 1 else 2 end ,d.NombreDistribuidor
)SELECT *,
SUM(monto) OVER(PARTITION BY nombre_dia, distribuidor
ORDER BY fecha, nombre_dia, distribuidor ROWS UNBOUNDED PRECEDING) AS RunningTotal
from t where distribuidor='XYZ'
一个简单的输出样本将是
monday XYZ 5 5
tuesday XYZ 1 6
wednesday XYZ 2 8
..
....
monday XYZ 2 2 -- restart value every monday
tuesday XYZ 2 4
..
...
答案 0 :(得分:1)
我刚刚在rextester中设置了一个示例:http://rextester.com/MEXHM63945
不要试图在每个星期一打破累积金额,只需将星期一设置为星期的第一天,而将SUM()设置为提供者和WeekOfMonth。
我还没有测试过,但我认为你可以在不使用CTE窗口功能的情况下获得它。 (看看答案的结尾。)
-- Set monday first day of week
SET DATEFIRST 1;
create table #data ([date] datetime, provider varchar(10), value int);
insert into #data values
('2017-01-02', 'XYZ', 1),
('2017-01-03', 'XYZ', 5),
('2017-01-04', 'XYZ', 3),
('2017-01-05', 'XYZ', 5),
('2017-01-06', 'XYZ', 4),
('2017-01-07', 'XYZ', 11),
('2017-01-08', 'XYZ', 11),
('2017-01-09', 'XYZ', 1),
('2017-01-10', 'XYZ', 5),
('2017-01-11', 'XYZ', 3),
('2017-01-12', 'XYZ', 5),
('2017-01-13', 'XYZ', 4),
('2017-01-14', 'XYZ', 11),
('2017-01-15', 'XYZ', 11);
SELECT provider, DATEPART(WEEK, date) as week_of_year, value,
sum(value) OVER (Partition by provider, DATEPART(WEEK, date) ORDER BY date, provider) Acm
FROM #data
ORDER BY date, provider;
结果如下:
+----------+--------------+-------+-----+
| provider | week_of_year | value | Acm |
+----------+--------------+-------+-----+
| XYZ | 2 | 1 | 1 |
+----------+--------------+-------+-----+
| XYZ | 2 | 5 | 6 |
+----------+--------------+-------+-----+
| XYZ | 2 | 3 | 9 |
+----------+--------------+-------+-----+
| XYZ | 2 | 5 | 14 |
+----------+--------------+-------+-----+
| XYZ | 2 | 4 | 18 |
+----------+--------------+-------+-----+
| XYZ | 2 | 11 | 29 |
+----------+--------------+-------+-----+
| XYZ | 2 | 11 | 40 |
+----------+--------------+-------+-----+
| XYZ | 3 | 1 | 1 |
+----------+--------------+-------+-----+
| XYZ | 3 | 5 | 6 |
+----------+--------------+-------+-----+
| XYZ | 3 | 3 | 9 |
+----------+--------------+-------+-----+
| XYZ | 3 | 5 | 14 |
+----------+--------------+-------+-----+
| XYZ | 3 | 4 | 18 |
+----------+--------------+-------+-----+
| XYZ | 3 | 11 | 29 |
+----------+--------------+-------+-----+
| XYZ | 3 | 11 | 40 |
+----------+--------------+-------+-----+
我认为这应该可以胜任:
SELECT
CAST(t.fecha AS DATE) fecha
, d.NombreDistribuidor distribuidor
, SUM(tr.Monto) OVER (PARTITION BY d.NombreDistribuidor, DATEPART(week, CAST(t.fecha AS DATE))
ORDER BY CAST(t.fecha AS DATE), d.NombreDistribuidor) monto
FROM
HechosTransferencia tr
INNER JOIN DimensionTiempo t ON tr.DimensionTiempoId=t.DimensionTiempoId
INNER JOIN DimensionDistribuidor d ON d.DimensionDistribuidorId=tr.DimensionDistribuidorId
WHERE
(t.Fecha BETWEEN DATEADD(MONTH, DATEDIFF(MONTH, - 2, GETDATE()) - 2, 0) AND GETDATE())
GROUP BY
CAST(t.fecha AS DATE), d.NombreDistribuidor;
答案 1 :(得分:1)
根据McNets提出的解决方案,我的问题的答案是:
SET DATEFIRST 1;
WITH t (fecha, distribuidor, monto)as (
SELECT CAST(t.fecha AS DATE)fecha
,d.NombreDistribuidor distribuidor
,sum(tr.Monto)monto
from HechosTransferencia tr inner join DimensionTiempo t on tr.DimensionTiempoId=t.DimensionTiempoId
inner join DimensionDistribuidor d on d.DimensionDistribuidorId=tr.DimensionDistribuidorId
WHERE (t.Fecha BETWEEN DATEADD(MONTH, DATEDIFF(MONTH, - 2, GETDATE()) - 2, 0) AND GETDATE())
group by CAST(t.fecha AS DATE)
,d.NombreDistribuidor
)SELECT *
,sum(monto) OVER (Partition by distribuidor, DATEPART(WEEK, fecha) ORDER BY fecha, distribuidor)RunningTotal
from t;