微前端-qiankun學習記錄( 一 )
阿新 • • 發佈:2020-12-21
庫存賬齡報表開發總結——Sqlserver LAG()的使用
-
開發需求
根據出入庫流水明細,查詢對應產品庫存狀態:包含庫齡、庫存量及其金額等。
注意:出庫按照先入先出的規則進行。
例如:
物品 數量 日期 A 10 2020-01-01 A 20 2020-02-01 A 30 2020-03-03 A -5 2020-04-10 A -35 2020-05-15 A 300 2020-06-18 A -60 2020-11-10 A 90 2020-11-30 A -100 2020-12-12 B 20 2020-07-15 B 40 2020-10-11 B -30 2020-11-11 上面表示一個出入庫流水明細
-- 建表,並插入資料 CREATE TABLE T_StkFlowDetail( id int
以
2020-12-31
為截止日期去判定最終展示報表形式物品 庫存 0-60天 61-120天 121-180天 181-240天 241-300天 301-360天 A 250 90 0 0 160 0 0 B 30 0 30 0 0 0 0 -
需求分析
-
根據每次入庫時間獲取各時間段的庫齡
-
根據出庫按照先入先出的規則扣減庫存
-
根據庫齡將對應的庫存、金額等相關資料展示
-
綜上:該報表的難度在於如何先入先出的扣減庫存
-
-
函式講解
-
LAG 詳細介紹:https://www.yiibai.com/sqlserver/sql-server-lag-function.html
SQL Server
LAG()
是一個Window函式,它提供對當前行之前的指定物理偏移量的行的訪問。換句話說,通過使用
LAG()
函式,可以從當前行訪問上一行的資料或上一行之前的行,依此類推。LAG()
函式對於將當前行的值與前一行的值進行比較非常有用-- 使用語法 LAG(return_value ,offset [,default]) OVER ( [PARTITION BY partition_expression, ... ] ORDER BY sort_expression [ASC | DESC], ... )
-
DATEDIFF 詳細介紹:https://www.yiibai.com/sqlserver/sql-server-datediff-function.html
計算年,月,周等兩個日期之間的差值
-- 使用語法 DATEDIFF( date_part , start_date , end_date
-
-
解決方案
- 查詢每個物品各時間段有庫存情況下的庫齡
SELECT goods_code, stk_date, diff_days, current_stk_nums, current_stk_nums - ISNULL( LAG ( current_stk_nums ) OVER ( partition BY goods_code ORDER BY stk_date ), 0 ) current_stk_row_nums FROM ( SELECT goods_code, num, stk_date, DATEDIFF( DAY, stk_date, '2020-12-31' ) diff_days, SUM ( CASE WHEN num < 0 THEN num ELSE 0 END ) OVER ( PARTITION BY goods_code ) + SUM ( CASE WHEN num > 0 THEN num ELSE 0 END ) OVER ( PARTITION BY goods_code ORDER BY stk_date ) current_stk_nums FROM T_StkFlowDetail WHERE stk_date <= '2020-12-31' ) t WHERE current_stk_nums > 0 AND num > 0
-
執行結果
-
此處建議將上述sql寫成函式,方便報表輸出
CREATE FUNCTION [dbo].[FUNC_GetStockAge] ( @end_date DATE ) RETURNS TABLE AS RETURN ( SELECT goods_code, stk_date, diff_days, current_stk_nums, current_stk_nums - ISNULL( LAG ( current_stk_nums ) OVER ( partition BY goods_code ORDER BY stk_date ), 0 ) current_stk_row_nums FROM ( SELECT goods_code, num, stk_date, DATEDIFF( DAY, stk_date, @end_date ) diff_days, SUM ( CASE WHEN num < 0 THEN num ELSE 0 END ) OVER ( PARTITION BY goods_code ) + SUM ( CASE WHEN num > 0 THEN num ELSE 0 END ) OVER ( PARTITION BY goods_code ORDER BY stk_date ) current_stk_nums FROM T_StkFlowDetail WHERE stk_date <= @end_date ) t WHERE current_stk_nums > 0 AND num > 0 )
-
報表輸出語句
SELECT t.goods_code '物品', t.num '庫存', SUM(IIF(t1.diff_days BETWEEN 0 AND 60,t1.current_stk_row_nums,0)) AS '0-60天', SUM(IIF(t1.diff_days BETWEEN 61 AND 120,t1.current_stk_row_nums,0)) AS '61-120天', SUM(IIF(t1.diff_days BETWEEN 121 AND 180,t1.current_stk_row_nums,0)) AS '121-180天', SUM(IIF(t1.diff_days BETWEEN 181 AND 240,t1.current_stk_row_nums,0)) AS '181-240天', SUM(IIF(t1.diff_days BETWEEN 241 AND 300,t1.current_stk_row_nums,0)) AS '241-300天', SUM(IIF(t1.diff_days BETWEEN 301 AND 360,t1.current_stk_row_nums,0)) AS '301-360天' FROM ( -- 截止2020-12-31各物品的庫存 SELECT goods_code,SUM(num) num FROM T_StkFlowDetail WHERE stk_date < '2020-12-31' GROUP BY goods_code HAVING SUM(num) > 0 )t LEFT JOIN FUNC_GetStockAge('2020-12-31') t1 ON t1.goods_code = t.goods_code WHERE t.num > 0 GROUP BY t.goods_code,t.num
-
輸出結果