2013-09-24 91 views
0

我是SQL中非常新(剛開始3天后),我有一個問題,並希望有人能夠幫助我。循環日期和返回星期tsql

我有一個查詢創建日期循環來根據傳入的日期返回星期數。這裏的想法是通過幾天,幾個月和幾年的循環,並返回給我一週的價值。但是由於這些原因,我得到了相同結果的多個條目。

例如,我越來越:

period_wk_key period_yr_key period_week period_week_day period_week_full_desc 
--------------- -------------- ------------ -------------- ----------------------- 
200001   2000   1    6    2000 WEEK 1 
200001   2000   1    6    2000 WEEK 1 
200001   2000   1    6    2000 WEEK 1 
.    .    .    .    . 
200002   2000   2    6    2000 WEEK 2 
200002   2000   2    6    2000 WEEK 2 
200002   2000   2    6    2000 WEEK 2 
.    .    .    .    .  
200003   2000   3    6    2000 WEEK 3 

每個period_wk_key將返回我7個類似的行這不是我想要的東西。

理想的情況應該是:

period_wk_key period_yr_key period_week period_week_day period_week_full_desc 
--------------- -------------- ------------ -------------- ----------------------- 
200001   2000   1    6    2000 WEEK 1 
200002   2000   2    6    2000 WEEK 2 
200003   2000   3    6    2000 WEEK 3 
200004   2000   4    6    2000 WEEK 4 

我需要知道一個方法來限制從環路輸出的數量,這樣我可以有不同的記錄,而不是多個類似的行。我附上了一個代碼如下。這可能是對你們許多人的廢話,但這只是我第三天開始編寫腳本。非常感謝您提供的任何幫助。

DECLARE @iStartYear INT 
    SET @iStartYear = 2000 
    DECLARE @iEndYear INT 
    SET @iEndYear = 2030 
    DECLARE @iMth INT 
    SET @iMth = 1 
    DECLARE @iDay INT 
    SET @iDay = 1 
    DECLARE @iWeek INT 

`DECLARE @StartDate DATETIME 
WHILE (@iStartYear <= @iEndYear) 
    BEGIN 
     WHILE (@iMth <= 12) 
     BEGIN 
     WHILE (@iDay <= DATEDIFF(DAY,DATEADD(DAY, 0, DATEADD(m, ((@iStartYear - 1900) * 12) + @iMth - 1, 0)),DATEADD(DAY, 0, DATEADD(m, ((@iStartYear - 1900) * 12) + @iMth, 0))))) 
       BEGIN ` 

    SET @iWeek = (DATEPART(dy, CONVERT(DATETIME, CONVERT(VARCHAR(4), @iStartYear) + '/' + CONVERT(VARCHAR(2), @iMth) + '/' + CONVERT(VARCHAR(2), @iDay))) - 1)/7 + 1; 

    INSERT INTO dim_period_week (period_wk_key, period_yr_key, period_week, period_week_full_desc,start_date, end_date, period_week_day) 
    VALUES ( 
    (SELECT CASE WHEN @iWeek < 10 THEN 
     CAST((@iStartYear) AS VARCHAR) + '0' + CAST((@iWeek) AS VARCHAR) 
    ELSE 
     CAST((@iStartYear) AS VARCHAR)+ CAST((@iWeek) AS VARCHAR) 
    END),   
    @iStartYear, 
    (SELECT (DATEPART(dy, CONVERT(DATETIME, CONVERT(VARCHAR(4), @iStartYear) + '/' + CONVERT(VARCHAR(2), @iMth) + '/' + CONVERT(VARCHAR(2), @iDay))) - 1)/7 + 1), 

    (SELECT CAST((@iStartYear) AS VARCHAR) + ' ' + 'WEEK' + ' ' + CAST((@iWeek) AS VARCHAR)), 
    (SELECT DATEADD(wk,@iWeek-1, DATEADD(yy,@iStartYear-1900,0))), --START DATE 
    (SELECT DATEADD(wk,@iWeek, DATEADD(yy,@iStartYear-1900,0)) -1), --END DATE 
    (SELECT DATEDIFF(DAY, DATEADD(wk,@iWeek-1, DATEADD(yy,@iStartYear-1900,0)), DATEADD(wk,@iWeek, DATEADD(yy,@iStartYear-1900,0)) -1)) 
)       
    `SET @iDay = @iDay + 1 
    END    
    SET @iDay = 1 
    SET @iMth = @iMth + 1 
    END 
    SET @iMth = 1 
    SET @iStartYear = @iStartYear + 1 
    END 
` 
+2

瞭解SQL的一個重要的事情不是循環思考。根據數據集思考。 – podiluska

+0

請解釋你的輸入和ouptuts。 'DATEPART(wk,GETDATE())'不能滿足您的需求?我99%是「做錯了」,但是你要付出很大的努力才能得到讚揚,這比大多數其他海報可以說的要多得多。 –

+0

嗨..我不使用getdate()的原因是因爲通過這樣做,它只會返回基於當前日期的星期,這不是我想要的。我的桌子是空白的,沒有任何數據。我正在寫一個查詢來通過循環插入日期值(從2000年到2030年),並從中提取周。我設法做到這一點,但唯一的問題是我得到多個條目,我相信它可能需要做一些'天'循環。 –

回答

0

你是循環的每一天,但在這一天永遠級存儲,從而可以在需要你正在做的7倍之多插入。在INSERT語句上方添加以下內容

IF DATEPART(weekday, CAST(CAST(@iStartYear * 10000 + @iMth * 100 + @iDay AS VARCHAR(8)) AS datetime)) = 1 
INSERT INTO dim_period_week ... 
0

下面是使用數字表的基於集合的方法。

IF OBJECT_ID('tempdb.dbo.#Numbers') IS NOT NULL DROP TABLE #Numbers 
GO 
DECLARE @startDate DATETIME = '20000101' 
SELECT 
    (a.Number * 256) + b.Number AS Number 
INTO #Numbers 
FROM 
    (SELECT number FROM master..spt_values WHERE type = 'P' AND number <= 255) a (Number), 
    (SELECT number FROM master..spt_values WHERE type = 'P' AND number <= 255) b (Number) 
WHERE 
    (a.Number * 256) + b.Number BETWEEN 0 AND 1617 

SELECT 
    WeekKey = CAST(YEAR(DATEADD(day, N.Number * 7, @startDate)) * 100 + DATEPART(week, DATEADD(day, N.Number * 7, @startDate)) AS VARCHAR(10)), 
    TheYear = YEAR(DATEADD(day, N.Number * 7, @startDate)), 
    TheWeek = DATEPART(week, DATEADD(day, N.Number * 7, @startDate)), 
    TheWeekDay= DATEPART(weekday, DATEADD(day, N.Number * 7, @startDate)), 
    WeekDetail= DATENAME(year, DATEADD(day, N.Number * 7, @startDate)) + ' WEEK ' + DATENAME(week, DATEADD(day, N.Number * 7, @startDate)), 
    StartDate = DATEADD(day, N.Number * 7, @startDate), 
    EndDate = DATEADD(day, 6, DATEADD(day, N.Number * 7, @startDate)) 
FROM #Numbers N 
ORDER BY 1