我是SQL的新手(仅在3天后开始),我遇到了一个问题,希望有人能够帮助我。
我有一个创建日期循环的查询,根据传入的日期返回周数。这里的想法是通过几天,几个月和几年的循环,并返回一周的价值。但由于这些原因,我得到了相同结果的多个条目。
例如。我得到了:
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
我需要知道一种限制循环输出数量的方法,这样我就可以拥有不同的记录而不是多个相似的行。我在下面附上了一个代码。它可能是你们许多人的废话,但这只是我开始编写脚本的第3天。非常感谢任何帮助。
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
`
答案 0 :(得分:0)
您每天都在进行循环,但从不在日期级别进行存储,因此您根据需要进行了7次INSERT。在INSERT语句上方添加以下内容
IF DATEPART(weekday, CAST(CAST(@iStartYear * 10000 + @iMth * 100 + @iDay AS VARCHAR(8)) AS datetime)) = 1
INSERT INTO dim_period_week ...
答案 1 :(得分: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