1. 程式人生 > 程式設計 >Spring基於註解讀取外部配置檔案

Spring基於註解讀取外部配置檔案

技術標籤:方法總結sqlsqlserver

庫存賬齡報表開發總結——Sqlserver LAG()的使用

  • 開發需求

    根據出入庫流水明細,查詢對應產品庫存狀態:包含庫齡、庫存量及其金額等。

    注意:出庫按照先入先出的規則進行。

    例如:

    物品數量日期
    A102020-01-01
    A202020-02-01
    A302020-03-03
    A-52020-04-10
    A-352020-05-15
    A3002020-06-18
    A-602020-11-10
    A902020-11-30
    A-1002020-12-12
    B202020-07-15
    B402020-10-11
    B-302020-11-11

    上面表示一個出入庫流水明細

    -- 建表,並插入資料
    CREATE TABLE T_StkFlowDetail(
    	id int
    primary key not null, goods_code varchar(20) null, num decimal(16,7) null, stk_date date not null ) INSERT INTO [dbo].[T_StkFlowDetail]([id], [goods_code], [num], [stk_date]) VALUES (1, 'A', 10.0000000, '2020-01-01'); INSERT INTO [dbo].[T_StkFlowDetail]([id], [goods_code], [num], [stk_date]) VALUES (2, 'A',
    20.0000000, '2020-02-01'); INSERT INTO [dbo].[T_StkFlowDetail]([id], [goods_code], [num], [stk_date]) VALUES (3, 'A', 30.0000000, '2020-03-03'); INSERT INTO [dbo].[T_StkFlowDetail]([id], [goods_code], [num], [stk_date]) VALUES (4, 'A', -5.0000000, '2020-04-10'); INSERT INTO [dbo].[T_StkFlowDetail]([id], [goods_code], [num], [stk_date]
    ) VALUES (5, 'A', -35.0000000, '2020-05-15'); INSERT INTO [dbo].[T_StkFlowDetail]([id], [goods_code], [num], [stk_date]) VALUES (6, 'A', 300.0000000, '2020-06-18'); INSERT INTO [dbo].[T_StkFlowDetail]([id], [goods_code], [num], [stk_date]) VALUES (7, 'A', -60.0000000, '2020-11-10'); INSERT INTO [dbo].[T_StkFlowDetail]([id], [goods_code], [num], [stk_date]) VALUES (8, 'A', 90.0000000, '2020-11-30'); INSERT INTO [dbo].[T_StkFlowDetail]([id], [goods_code], [num], [stk_date]) VALUES (9, 'A', -100.0000000, '2020-12-12'); INSERT INTO [dbo].[T_StkFlowDetail]([id], [goods_code], [num], [stk_date]) VALUES (10, 'B', 20.0000000, '2020-07-15'); INSERT INTO [dbo].[T_StkFlowDetail]([id], [goods_code], [num], [stk_date]) VALUES (11, 'B', 40.0000000, '2020-10-11'); INSERT INTO [dbo].[T_StkFlowDetail]([id], [goods_code], [num], [stk_date]) VALUES (12, 'B', -30.0000000, '2020-11-11');

    2020-12-31為截止日期去判定最終展示報表形式

    物品庫存0-60天61-120天121-180天181-240天241-300天301-360天
    A250900016000
    B300300000
  • 需求分析

    • 根據每次入庫時間獲取各時間段的庫齡

    • 根據出庫按照先入先出的規則扣減庫存

    • 根據庫齡將對應的庫存、金額等相關資料展示

    • 綜上:該報表的難度在於如何先入先出的扣減庫存

  • 函式講解

  • 解決方案

    • 查詢每個物品各時間段有庫存情況下的庫齡
    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
    
    • 執行結果
      [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-oZqM2PbZ-1608467958242)(/Users/wangzhili/Library/Application Support/typora-user-images/image-20201220201134827.png)]

    • 此處建議將上述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
    
  • 輸出結果
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-uBvsfWNn-1608467958243)(/Users/wangzhili/Library/Application Support/typora-user-images/image-20201220203646984.png)]