SQL Server獲取連續區間的日期


目前實現方法有:

  1. 通過系統表master..spt_values獲取
  2. 用WHILE循環獲取
  3. 游標獲取
  4. CTE遞歸(感謝博友提供)

 

方法一:通過系統表master..spt_values獲取

1、獲取連續的日

-- 獲取連續區間的日期
DECLARE @StartTime DATE = '2019-03-08', -- 開始時間
        @EndTime   DATE = '2019-03-18' -- 結束時間

SELECT CONVERT(NVARCHAR(10),DATEADD(DAY,number,@StartTime),120) AS DayTime
  FROM master..spt_values  
 WHERE type = 'p' 
   AND number <= DATEDIFF(DAY,@StartTime,@EndTime)

 

 

 
2、獲取連續的月

-- 獲取連續區間的月份
DECLARE @StartTime DATE = '2019-03-08', -- 開始時間
        @EndTime   DATE = '2019-12-28' -- 結束時間

SELECT CONVERT(VARCHAR(7),DATEADD(MONTH,number,@StartTime),120) AS MonthTime
  FROM master..spt_values WITH (NOLOCK) 
 WHERE type='P' 
   AND number <= DATEDIFF(MONTH,@StartTime,@EndTime)

 

3、獲取連續的年

-- 獲取連續區間的年份
DECLARE @StartTime DATE = '2019-03-08', -- 開始時間
        @EndTime   DATE = '2020-03-08' -- 結束時間

SELECT CONVERT(VARCHAR(4),DATEADD(YEAR,number,@StartTime),120) AS YearTime
  FROM master..spt_values WITH (NOLOCK) 
 WHERE type='P' 
   AND number <= DATEDIFF(YEAR,@StartTime,@EndTime)

 

master..spt_values原理:

通過number來實現年月日的加減,因為number值最大是2047,所以只能連續加2047。

如圖:結束時間是'2026-03-28',但我們降序可以看到,從2019-03-08只能增加連續2047天,如此2024-10-24之后的日期就沒有了。

所以如果連續區間超過了2048,則此方法不適用,此時可以用以下方法二來實現

 

方法二:用WHILE循環獲取

1、獲取連續的日

-- 連續獲取天
DECLARE @StartTime DATE = '2019-03-08', -- 開始時間
        @EndTime   DATE = '2019-03-18' -- 結束時間

-- 創建臨時表#DateTime存儲日期
CREATE TABLE #DateTime
(
    DayTime DATE
);

-- 循環獲取日期插入臨時表
WHILE @StartTime <= @EndTime
BEGIN
    INSERT INTO #DateTime (DayTime)
    VALUES (@StartTime);
    SET @StartTime = DATEADD(DAY, 1, @StartTime);
END;

SELECT DayTime FROM #DateTime;

-- 刪除臨時表
DROP TABLE #DateTime;

 

 

2、獲取連續的月

-- 連續獲取的月
DECLARE @StartTime DATE = '2019-03-08', -- 開始時間
        @EndTime   DATE = '2019-12-28' -- 結束時間

-- 創建臨時表#MonthTime存儲日期
CREATE TABLE #MonthTime
(
    MonthTime VARCHAR(7)
);



-- 循環獲取日期插入臨時表
WHILE @StartTime <= @EndTime
BEGIN
    INSERT INTO #MonthTime (MonthTime)
    VALUES (CONVERT(VARCHAR(7),@StartTime));
    SET @StartTime = DATEADD(MONTH, 1, @StartTime);
END;

SELECT MonthTime FROM #MonthTime;

-- 刪除臨時表
DROP TABLE #MonthTime;

 

3、獲取連續的年

-- 連續獲取的月
DECLARE @StartTime DATE = '2019-03-08', -- 開始時間
        @EndTime   DATE = '2025-03-28' -- 結束時間

-- 創建臨時表#YearTime存儲日期
CREATE TABLE #YearTime
(
    YearTime VARCHAR(4)
);



-- 循環獲取日期插入臨時表
WHILE @StartTime <= @EndTime
BEGIN
    INSERT INTO #YearTime (YearTime)
    VALUES (CONVERT(VARCHAR(4),@StartTime));
    SET @StartTime = DATEADD(YEAR, 1, @StartTime);
END;

SELECT YearTime FROM #YearTime;

-- 刪除臨時表
DROP TABLE #YearTime;

 

方法三:用游標獲取,原理和WHILE循環相似,此處不再展示

 

方法四:評論區博友說的CTE遞歸

 

DECLARE @StartTime DATE = '2018-12-08', -- 開始時間
@EndTime DATE = '2019-03-18' -- 結束時間
;
-- 獲取連續天
WITH CteDateDay AS
(
SELECT @StartTime DayTime
UNION ALL
SELECT DATEADD(DAY,1,DayTime) DayTime FROM CteDateDay
WHERE DayTime<@EndTime
)
SELECT DayTime FROM CteDateDay
OPTION (MAXRECURSION 0)
;

-- 獲取連續月
WITH CteDateMonth AS
(
SELECT CONVERT(VARCHAR(7),@StartTime,120) MonthTime
UNION ALL
SELECT CONVERT(VARCHAR(7),DATEADD(MONTH,1,CAST(MonthTime+'-01' AS DATE)),120) DayTime FROM CteDateMonth
WHERE MonthTime<CONVERT(VARCHAR(7),@EndTime,120)
)
SELECT MonthTime FROM CteDateMonth
OPTION (MAXRECURSION 0)
;

-- 獲取連續年
WITH CteDateYear AS
(
SELECT DATEPART(YEAR,@StartTime) YearTime
UNION ALL
SELECT YearTime+1 DayTime FROM CteDateYear
WHERE YearTime<DATEPART(YEAR,@EndTime)
)
SELECT YearTime FROM CteDateYear
OPTION (MAXRECURSION 0)

 

 

 

 

如果有什么好的方法和建議,歡迎大家來指點,謝謝!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM