2011-10-18 12 views
20

के बीच की तारीखों के साथ एक अस्थायी तालिका को पॉप्युलेट करने का सबसे आसान तरीका 2 दिनांक पैरामीटर सहित और तिथियों के साथ एक अस्थायी तालिका को पॉप्युलेट करने का सबसे आसान तरीका क्या है। मुझे केवल महीने की तारीख के पहले दिन की आवश्यकता है।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 

उत्तर

23

यह काम करता है, भले ही @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) 
+2

+1 क्या मैंने उल्लेख किया कि मुझे रिकर्सन पसंद है? –

+0

उदाहरण के रूप में चल रहा है-परिणाम एक रिकॉर्ड में है। मैं क्या खो रहा हूँ? –

+0

@ElanHasson, क्या आपने स्टार्टडेट सेट किया है और विभिन्न महीनों में समाप्त किया है (यदि स्टार्टडेट महीने का पहला नहीं है, तो यह अगले महीने के पहले का उपयोग करता है)। – GilM

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<[email protected]) 
begin 
insert into @temp 
values (@StartDate) 
select @StartDate=DATEADD(MM,1,@StartDate) 
end 
select * from @temp 
में लौट आए चाहते

StartDate

के महीने के प्रारंभिक दिन में वापस जाकर काम करता है, भले ही @StartDate महीने के पहले दिन नहीं है
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 
+1

+1, आप भी कर सकता है 'DateDiff (MONTH, 0, @StartDate) +' DateDiff (MONTH, 0 के बजाय v.number', DATEADD (MONTH, v.number, @StartDate)) '। –

+0

सहमत हैं। यह आसान है। –

13
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) 
5

इस एसक्यूएल में परीक्षण किया जाता है 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 
... 
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 साल के डेटा के आंकड़ों को पॉप्युलेट कर सकती है, और बहुत अच्छी लगती है, इसलिए मैं वास्तव में दिनों को बढ़ाने के लिए इस विधि की अनुशंसा नहीं करता हूं। अशक्त दिनांकों

+0

कि क्रॉस जॉइन चाल शांत है। अन्य समाधानों की तुलना में हजारों पंक्तियां तुरंत निष्पादित होती हैं। –

1

सुधार:

IF OBJECT_ID('tempdb..#dim') IS NOT NULL 

    DROP TABLE #dim 

CREATE TABLE #dim ([date] DATE) 

if not @Begin_Date is null and not @End_Date is null 

begin 
    INSERT #dim([date]) 
    SELECT d 
    FROM(

     SELECT 
      d = DATEADD(DAY, rn - 1, @Begin_Date) 
     FROM 
     (
      SELECT TOP (DATEDIFF(DAY, @Begin_Date, @End_Date)) 
       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; 
end 
संबंधित मुद्दे