sql server 取起始日期到结束日期中自然月最后一天,与日期维度行转列
sql server 取起始日期到结束日期中自然月最后一天,与日期维度行转列,这里记录一下。
这段SQL代码实现了从起始日期到结束日期区间内获取各自然月最后一天,并对库存数据进行行转列处理。主要步骤包括:1)定义日期变量并处理结束日期;2)计算日期区间月份数;3)创建临时表存储各月最后一天;4)查询指定日期区间的库存数据;5)使用PIVOT将日期维度转换为列,展示各物料在不同月末的库存数量。代码特别处理了当日作为结束日期的情况,并考虑了日期区间超过30天的月份计算。
DECLARE @BEGINTIME VARCHAR(20),@ENDTIME VARCHAR(20)
SET @BEGINTIME=‘2025-04-27’
SET @ENDTIME=‘2025-09-1’;
IF(CONVERT(DATETIME,@ENDTIME)=CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE())))
BEGIN
SET @ENDTIME=(SELECT CONVERT(VARCHAR(10),DATEADD(D,-1,TRY_CAST(@ENDTIME AS DATETIME)),23))
END
DECLARE @ENDTIME1 VARCHAR(10),@DATEIFF_M INT
SET @ENDTIME1=(SELECT CONVERT(VARCHAR(10),DATEADD(D,1,TRY_CAST(@ENDTIME AS DATETIME)),23))/结束日期+1天/
SET @DATEIFF_M=DATEDIFF(DAY,@BEGINTIME,@ENDTIME1)/30;/日期区间月份/
IF(OBJECT_ID(‘tempdb…#LastDayOfMonth’) IS NOT NULL)
BEGIN
DROP TABLE #LastDayOfMonth
END
CREATE TABLE #LastDayOfMonth(CMonth VARCHAR(10))
DECLARE @BEGINTIME1 DATETIME,@i INT
SET @BEGINTIME1=@BEGINTIME
SET @i=0
IF(@DATEIFF_M>0)
BEGIN
WHILE(@i<@DATEIFF_M)
BEGIN
IF(NOT EXISTS(SELECT * FROM #LastDayOfMonth))
BEGIN
INSERT INTO #LastDayOfMonth(CMonth)VALUES(CONVERT(VARCHAR(10),CONVERT(DATETIME,@BEGINTIME),112))
END
ELSE
BEGIN
INSERT INTO #LastDayOfMonth(CMonth)VALUES(CONVERT(VARCHAR(10), EOMONTH(DATEADD(DAY,@i*30,EOMONTH(@BEGINTIME))),112))
SET @i=@i+1
END
END
END
INSERT INTO #LastDayOfMonth(CMonth)VALUES(CONVERT(VARCHAR(10),CONVERT(DATETIME,@ENDTIME),112))
SELECT * FROM #LastDayOfMonth
IF(OBJECT_ID(‘tempdb…#tab0’) IS NOT NULL)
BEGIN
DROP TABLE #tab0
END
SELECT t0.F_BHR_MATERIALID FMATERIALID
,t1.FNUMBER FMATERIALNUMBER,t0.F_BHR_DATE,t0.F_BHR_STOCKID,t0.F_BHR_STOCKORGID
, t0.F_BHR_StockQty FQTY
INTO #tab0
FROM BHR_T_STK_HisInventory t0
JOIN T_BD_MATERIAL t1 ON t1.FMATERIALID=t0.F_BHR_MATERIALID
WHERE t0.F_BHR_DATE IN (SELECT * FROM #LastDayOfMonth)
AND t0.F_BHR_STOCKID IN(107673,1938233,107654,934634,1582878,2123102,3152742)
IF(OBJECT_ID(‘tempdb…#Mate_List’) IS NOT NULL)
BEGIN
DROP TABLE #Mate_List
END
IF(OBJECT_ID(‘tempdb…#tab1’) IS NOT NULL)
BEGIN
DROP TABLE #tab1
END
SELECT FMATERIALID,FMATERIALNUMBER,CONVERT(VARCHAR(10),F_BHR_DATE,112) F_BHR_DATE,F_BHR_STOCKID,F_BHR_STOCKORGID,FQTY INTO #tab1 FROM #tab0
DECLARE @sql1 NVARCHAR(MAX),@sql2 NVARCHAR(4000),@Cmonth NVARCHAR(30);
SELECT CMonth FROM #LastDayOfMonth
SELECT
@sql2=STUFF((SELECT ‘’,‘,[’ + t0.Cmonth+‘]’
FROM #LastDayOfMonth t0 FOR XML PATH(‘’)),1,1,‘’)
FROM #LastDayOfMonth t1
SET @sql1=‘SELECT * FROM ( SELECT FMATERIALID,FMATERIALNUMBER,F_BHR_STOCKID,F_BHR_STOCKORGID,F_BHR_DATE,FQTY FROM #tab1) p PIVOT(SUM(FQTY) FOR [F_BHR_DATE]IN (’+@sql2+‘) ) AS pvt ORDER BY pvt.FMATERIALNUMBER’
SELECT @sql1=@sql1
EXEC sp_executesql @sql1