2017-01-02 63 views
1

我期待有一個查詢和上一列積累,但它需要重新啓動每個星期一,但似乎TSQL窗口功能是不可能的窗口功能,使其 這裏是我的代碼:爲週一

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

You s應該添加標籤「tsql」到你的問題。那麼更多的人會看到它。 – tlemaster

+0

實際結果是什麼?累積金額? – McNets

+0

是的,它也是每個星期一由分銷商領域。 –

回答

1

我剛剛成立rextester一個例子:http://rextester.com/MEXHM63945

而不是試圖打破日e每週一的累計和,簡單地將星期一設置爲星期的第一天,以及提供者和WeekOfMonth的SUM()OVER PARTITION。

我還沒有測試過它,但我認爲你可以在不使用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; 
+0

嗨McNets,似乎theres與查詢錯誤,因爲我收到以下消息:消息8120,級別16,狀態1,行4 列'HechosTransferencia.Monto'在選擇列表中無效,因爲它不包含在集合函數或GROUP BY子句。 –

+0

我還沒有檢查過,'SUM(tr.Monto)'對我來說是一個聚合函數。也許這是不可能的,沒有使用CTE功能。 – McNets

+0

但在rextester的例子工作正常。 – McNets

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;