使用2个日期参数之间的日期填充临时表的最简单方法

时间:2011-10-18 20:03:57

标签: sql sql-server-2005 tsql

使用日期(包括2个日期参数之间)填充临时表的最简单方法是什么。我只需要每月的第一天约会。

例如,如果@StartDate ='2011-01-01'和@EndDate ='2011-08-01'

然后我希望在表中返回

2011-01-01
2011-02-01
2011-03-01
2011-04-01
2011-05-01
2011-06-01
2011-07-01
2011-08-01

8 个答案:

答案 0 :(得分:24)

即使@StartDate不是本月的第一个,这也有效。我假设如果它不是本月的开始,你想要从下个月的第一天开始。否则删除+1。:

;WITH cte AS (
SELECT CASE WHEN DATEPART(Day,@StartDate) = 1 THEN @StartDate 
            ELSE DATEADD(Month,DATEDIFF(Month,0,@StartDate)+1,0) END AS myDate
UNION ALL
SELECT DATEADD(Month,1,myDate)
FROM cte
WHERE DATEADD(Month,1,myDate) <=  @EndDate
)
SELECT myDate
FROM cte
OPTION (MAXRECURSION 0)

答案 1 :(得分:15)

declare @StartDate date = '2014-01-01';
declare @EndDate date = '2014-05-05';

;WITH cte AS (
    SELECT @StartDate AS myDate
    UNION ALL
    SELECT DATEADD(day,1,myDate) as myDate
    FROM cte
    WHERE DATEADD(day,1,myDate) <=  @EndDate
)
SELECT myDate
FROM cte
OPTION (MAXRECURSION 0)

答案 2 :(得分:7)

declare @StartDate datetime
declare @EndDate datetime
select @StartDate = '2011-01-01' ,  @EndDate = '2011-08-01'

select @StartDate= @StartDate-(DATEPART(DD,@StartDate)-1)

declare @temp  table
(
TheDate datetime
)
while (@StartDate<=@EndDate)
begin
insert into @temp
values (@StartDate )
select @StartDate=DATEADD(MM,1,@StartDate)
end
select * from @temp

即使@StartDate不是本月的第一天,也可以回到StartDate月初的第一天

答案 3 :(得分:6)

这是在SQL 2008 R2中测试的

Declare @StartDate datetime = '2015-03-01'
Declare @EndDate datetime = '2015-03-31'
declare @temp Table
(
DayDate datetime
);

WHILE @StartDate <= @EndDate
begin
 INSERT INTO @temp (DayDate) VALUES (@StartDate);
 SET @StartDate = Dateadd(Day,1, @StartDate);
end ;

select * from @temp

结果:

DayDate
-----------------------
2015-03-01 00:00:00.000
2015-03-02 00:00:00.000
2015-03-03 00:00:00.000
2015-03-04 00:00:00.000
...

答案 4 :(得分:1)

解决方案:

DECLARE  @StartDate DATETIME
        ,@EndDate DATETIME;

SELECT   @StartDate = '20110105'
        ,@EndDate = '20110815';

SELECT  DATEADD(MONTH, DATEDIFF(MONTH, 0, DATEADD(MONTH, v.number, @StartDate)), 0) AS FirstDay
--or Andriy M suggestion:
--SELECT    DATEADD(MONTH, DATEDIFF(MONTH, 0, @StartDate) + v.number, 0) AS FirstDay
INTO    #Results
FROM    master.dbo.spt_values v
WHERE   v.type = 'P'        
AND     DATEDIFF(MONTH, @StartDate, @EndDate) >= v.number;

SELECT  *
FROM    #Results;

DROP TABLE #Results;

结果:

FirstDay
-----------------------
2011-01-01 00:00:00.000
2011-02-01 00:00:00.000
2011-03-01 00:00:00.000
2011-04-01 00:00:00.000
2011-05-01 00:00:00.000
2011-06-01 00:00:00.000
2011-07-01 00:00:00.000
2011-08-01 00:00:00.000

答案 5 :(得分:1)

有趣的是,根据this article从枚举数据创建更快。

DECLARE @StartDate DATE = '10001201';
DECLARE @EndDate DATE   = '20000101';

DECLARE @dim TABLE ([date] DATE)

INSERT @dim([date])
SELECT d
FROM
(
  SELECT
      d = DATEADD(DAY, rn - 1, @StartDate)
  FROM 
  (
      SELECT TOP (DATEDIFF(DAY, @StartDate, @EndDate)) 
          rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
      FROM
          sys.all_objects AS s1
      CROSS JOIN
          sys.all_objects AS s2
      ORDER BY
          s1.[object_id]
  ) AS x
) AS y;

在我的机器上,大日期范围的速度提高约60%。递归方法可以在大约3秒钟内填充2000年的数据,并且看起来好多了,所以我不推荐这种方法只是为了增加数天。

答案 6 :(得分:1)

对空日期的更正:

$insData=array (
    0 => string 'sds' (length=3)
    1 => string 'dsds' (length=4)
    2 => string '1251' (length=4)
    3 => string 'jklj' (length=4)
    4 => string 'jklj' (length=4)
    5 => int 0
    6 => string 'jkkj' (length=4)
    7 => int 0
    8 => int 0
    9 => int 0
    10 => int 0
    11 => int 0
    12 => int 0
    13 => int 0
    14 => int 0
    15 => int 0
    16 => int 0
    17 => int 0
    18 => int 0
    19 => int 0
    20 => int 0
    21 => int 0
    22 => int 0
    23 => int 0
    24 => int 0
    25 => string '2017-06-28 10:06:24')

$escaped_values = array_map('mysql_real_escape_string',array_values($insData));
$values  = implode(", ", $insData);
$sql1 = "INSERT INTO `myTable` VALUES ($values)";
var_dump($sql1);
=> INSERT INTO `myTable` VALUES (sds, dsds, 1251, jklj, jklj, 0, jkkj, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2017-06-28)
try {
    $stmt1 = $bdd->prepare($sql1, array(PDO::ATTR_CURSOR, PDO::CURSOR_SCROLL));
    $stmt1->execute();
    $row1 = $stmt1->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_NEXT);
    $stmt1 = null;
  }
  catch (PDOException $e){
    print $e->getMessage();
  }

答案 7 :(得分:0)

CREATE TABLE #t (d DATE)

INSERT INTO #t SELECT GETDATE()

GO

INSERT #t SELECT DATEADD(DAY, -1, MIN(d)) FROM #t

GO 10