【SQL Server | T-SQL】SQL Server 2008 群組累計
有時候我們會在資料運算中加上了一個累計加總的資料欄,在SQL Server 2012中可以OVER子句來完成(SQL Server2012 OVER),而今天剛好就遇到需要計算庫存的累計數量,在網路上找了許久,2012可以用比較輕鬆的方式解決,但在2008就沒辦法使用,所以只好利用下面的方法來做到這項功能了
今天的需求是要統計同一個產品,從期初的庫存量計算時間範圍內的進貨數量及出貨數量的統計量,以下是小弟使用CTE的計算方式
有時候我們會在資料運算中加上了一個累計加總的資料欄,在SQL Server 2012中可以OVER子句來完成(SQL Server2012 OVER),而今天剛好就遇到需要計算庫存的累計數量,在網路上找了許久,2012可以用比較輕鬆的方式解決,但在2008就沒辦法使用,所以只好利用下面的方法來做到這項功能了
今天的需求是要統計同一個產品,從期初的庫存量計算時間範圍內的進貨數量及出貨數量的統計量,以下是小弟使用CTE的計算方式
DECLARE @Strat_date date = '2013/1/1',@End_date date ='2013/12/31';
--事先定義只要2013年的資料,在2013年以前計算後當作期初數量
WITH TEMP_START(mid,pqrt_START,ptotal_START) AS
(
SELECT mid,SUM(pqrt) AS pqrt_START,SUM(ptotal) AS ptotal_START FROM(
SELECT mid,SUM(pqrt) as pqrt,SUM(ptotal) AS ptotal FROM 進貨
WHERE date <@Strat_date
GROUP BY mid
UNION ALL
SELECT mid,SUM(pqrt) as pqrt,SUM(ptotal) AS ptotal FROM 進貨退回
WHERE date <@Strat_date
GROUP BY mid
UNION ALL
SELECT mid,SUM(pqrt)*-1 as pqrt,SUM(ptotal) AS ptotal FROM 銷貨
WHERE date <@Strat_date
GROUP BY mid
UNION ALL
SELECT mid,SUM(pqrt)*-1 as pqrt,SUM(ptotal) AS ptotal FROM 銷貨退回
WHERE date <@Strat_date
GROUP BY mid
) A
GROUP BY mid
),--計算期初數量,將進貨、進貨退回、銷貨、銷貨退回分別計算後,把資料表合併在一個CTE中
TEMP_UNION AS
(
SELECT *,pqrt AS pqrt_IN,ptotal AS ptotal_IN,0 as pqrt_OUT,0 as ptotal_OUT FROM 進貨
WHERE date >= @Strat_date AND date <=@End_date
UNION ALL
SELECT *,pqrt AS pqrt_IN,ptotal AS ptotal_IN,0 as pqrt_OUT,0 as ptotal_OUT FROM 進貨退回
WHERE date >= @Strat_date AND date <=@End_date
UNION ALL
SELECT *,0 AS pqrt_IN,0 AS ptotal_IN,pqrt as pqrt_OUT,ptotal as ptotal_OUT FROM 銷貨
WHERE date >= @Strat_date AND date <=@End_date
UNION ALL
SELECT *,0 AS pqrt_IN,0 AS ptotal_IN,pqrt as pqrt_OUT,ptotal as ptotal_OUT FROM 銷貨退回
WHERE date >= @Strat_date AND date <=@End_date
),--將2013年的進貨數量、進貨退回、銷貨量、銷貨退回合併在同一張資料表 (事先已將同一筆進貨單、進貨退回單、銷貨單、銷貨退回單依照產品代號加總)
TEMP_ACC AS
(
SELECT a.mid,a.date,a.code,SUM(b.pqrt_IN)
-SUM(b.pqrt_OUT) AS total_ACC FROM TEMP_UNION a
JOIN TEMP_UNION b
ON a.mid = b.mid AND a.date >= b.date AND (a.date != b.date OR a.code <= b.code)
GROUP BY a.mid,a.code,a.date
)--計算累計數量
/*
選取產品代號、日期、紀錄單號以便作為群組使用(防止同一天有多筆不同紀錄單號的進出貨)
先計算進貨的總計,與出貨的總計,然後將上一個CTE產生的進出貨數量相減取總和
合計的條件是:產品代號相同的,將小於自己日期的加總在一起,而後面的條件是若一天內有多筆紀錄,依照紀錄單號的大小加總
*/
SELECT TEMP_UNION.mid as [產品代號],TEMP_UNION.[date] as [日期],TEMP_UNION.code as [紀錄單號],
TEMP_UNION.flag as [進出貨],a.pqrt_START as [期初數量],TEMP_UNION.pqrt_IN as [進貨數量],TEMP_UNION.pqrt_OUT as [出貨數量],
a.pqrt_START + b.total_ACC as [累計數量]
FROM TEMP_UNION
LEFT OUTER JOIN TEMP_START a
ON TEMP_UNION.mid = a.mid
LEFT OUTER JOIN TEMP_ACC b
ON a.mid = b.mid AND TEMP_UNION.date = b.date AND TEMP_UNION.code = b.code
LEFT OUTER JOIN SL01
ON TEMP_UNION.mid = SL01.mid
WHERE a.mid IS NOT NULL
ORDER BY TEMP_UNION.mid,TEMP_UNION.date
這段T-SQL執行後會產生下列結果
---參考文章---
http://byronhu.wordpress.com/2011/05/14/%E7%94%A8-t-sql-%E7%B5%B1%E8%A8%88%E8%B3%87%E6%96%99/
大家好我是饅頭,希望大家喜歡我的文章
如果有錯誤的地方請不吝指教 ^_^