t-sql获取2个日期之间的所有日期

dcp*_*dcp 17 t-sql date

可能重复:
在一系列日期之间获取日期

假设我有2个日期(仅限日期部分,没有时间),我希望获得这两个日期之间的所有日期,并将它们插入表格中.有没有一种简单的方法来使用SQL语句(即没有循环)?

Ex:
Date1: 2010-12-01
Date2: 2010-12-04

Table should have following dates:
2010-12-01, 2010-12-02, 2010-12-03, 2010-12-04
Run Code Online (Sandbox Code Playgroud)

OMG*_*ies 49

假设SQL Server 2005+,使用递归查询:

WITH sample AS (
  SELECT CAST('2010-12-01' AS DATETIME) AS dt
  UNION ALL
  SELECT DATEADD(dd, 1, dt)
    FROM sample s
   WHERE DATEADD(dd, 1, dt) <= CAST('2010-12-04' AS DATETIME))
SELECT * 
  FROM sample
Run Code Online (Sandbox Code Playgroud)

返回:

 dt
 ---------
 2010-12-01 00:00:00.000
 2010-12-02 00:00:00.000
 2010-12-03 00:00:00.000
 2010-12-04 00:00:00.000
Run Code Online (Sandbox Code Playgroud)

使用CAST/CONVERT格式化您喜欢的格式.

使用参数开始和结束:

INSERT INTO dbo.YOUR_TABLE
  (datetime_column)
WITH sample AS (
    SELECT @start_date AS dt
    UNION ALL
    SELECT DATEADD(dd, 1, dt)
      FROM sample s
     WHERE DATEADD(dd, 1, dt) <= @end_date)
SELECT s.dt
  FROM sample s
Run Code Online (Sandbox Code Playgroud)


Mar*_*ith 18

你需要一个数字表.如果你没有永久的,那么生成一个比使用递归CTE 更有效.只要从缓冲区缓存中读取,永久性的就会更有效.

DECLARE @D1 DATE = '2010-12-01'
DECLARE @D2 DATE = '2010-12-04'

;WITH 
L0 AS (SELECT 1 AS c UNION ALL SELECT 1),
L1 AS (SELECT 1 AS c FROM L0 A CROSS JOIN L0 B),
L2 AS (SELECT 1 AS c FROM L1 A CROSS JOIN L1 B),
L3 AS (SELECT 1 AS c FROM L2 A CROSS JOIN L2 B),
L4 AS (SELECT 1 AS c FROM L3 A CROSS JOIN L3 B),
Nums AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS i FROM L4)
SELECT DATEADD(day,i-1,@D1)
 FROM Nums where i <= 1+DATEDIFF(day,@D1,@D2)
Run Code Online (Sandbox Code Playgroud)

  • 这应该标记为答案,而不是递归CTE.递归是一个循环,循环在SQL中较慢.请注意,Itzik的这种技术的原始示例使用TOP来限制交叉连接过度."我<="的地方不会阻止交叉连接,请参阅他的文章:http://sqlmag.com/sql-server/virtual-auxiliary-table-numbers (4认同)
  • 将选择部分更改为:SELECT TOP(1 + DATEDIFF(day,@ D1,@ D2))DATEADD(day,i-1,@ D1)FROM Nums (4认同)
  • 这是迄今为止最好的答案,并且不会受到递归问题的影响. (2认同)

Not*_*tMe 6

我刚刚做了这样的事情:

declare @dt datetime = '2010-12-01'
declare @dtEnd datetime = '2010-12-04'

WHILE (@dt < @dtEnd) BEGIN
    insert into table(datefield)
        values(@dt)
    SET @dt = DATEADD(day, 1, @dt)
END
Run Code Online (Sandbox Code Playgroud)