0

T-SQLクエリを使用して週の一時テーブルを作成する方法を知っている人はいますか?

グレゴリオ暦など、多くの種類の計算があると聞きました...私のニーズはISO週番号であり、一時テーブルへのバインドは週番号に依存します。

一時テーブルには 2 つの列があります:ISOWeekNoWeekName

ISOWeekNo   WeekName
1           01 Jan 2013 To 07 Jan 2013
2           08 Jan 2013 To 14 Jan 2013

ISO週番号に基づいてT-SQLクエリをプログラムで構築するにはどうすればよいですか?

更新: 年のみのパラメータを渡したい。例: 2013

4

3 に答える 3

4

編集:求められた年のみ終了するWHERE句を追加しました。

これはウィキペディアの説明と一致しているようで、最適化の余地があると確信しています。ミカエル、わかりやすい列のフォーマットコードをコピーしました。ありがとうございます。このコードは、ISOWEEK日付部分を使用しているため、SQLServer2008以降で機能します。

use tempdb
go

DECLARE  @Year          SMALLINT = 2013
        ,@FirstISOWKDay DATETIME

;WITH FindISOWEEKFirstDay AS
(
    SELECT DT   = DATEADD(DAY, -7, DATEFROMPARTS(@Year, 1, 1))
    UNION ALL
    SELECT DATEADD(DAY, 1, DT)
    FROM FindISOWEEKFirstDay
    WHERE DATEADD(DAY, 1, DT) < DATEADD(DAY, 14, DATEFROMPARTS(@Year, 1, 1))
)
SELECT TOP 1 @FirstISOWKDay = DT
FROM FindISOWEEKFirstDay
WHERE DATEPART(ISO_WEEK, DT) = 1
ORDER BY DT ASC -- Eliminate probability of arb sorting (Thanks Mikael)
;WITH Base10 (n) AS
(
    SELECT 1    UNION ALL   SELECT 1    UNION ALL   SELECT 1    UNION ALL
    SELECT 1    UNION ALL   SELECT 1    UNION ALL   SELECT 1    UNION ALL
    SELECT 1    UNION ALL   SELECT 1    UNION ALL   SELECT 1    UNION ALL
    SELECT 1    
)
,Base1000 (n) AS
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))-1
    FROM Base10 T1, Base10 T2, Base10 T3
)
SELECT   Start      = DATEADD(DAY, n*7, @FirstISOWKDay)
        ,[End]      = DATEADD(DAY, n*7 + 6, @FirstISOWKDay)
        ,Friendly   = CONVERT(VARCHAR(101), DATEADD(DAY, n*7, @FirstISOWKDay), 106)+' To '+CONVERT(VARCHAR(101), DATEADD(DAY, n*7 + 6, @FirstISOWKDay), 106)
        ,ISOWEEK    = DATEPART(ISO_WEEK, DATEADD(DAY, n*7, @FirstISOWKDay))
FROM Base1000
-- Filter to terminate, resulting only in sought year's calendar
WHERE DATEPART(YEAR, DATEADD(DAY, n*7 + 6, @FirstISOWKDay)) = @Year
于 2013-01-03T07:50:02.267 に答える
3
declare @Year int;
set @Year = 2016;

with C as
(
  select datefromparts(@Year, 1, 1) as D
  union all
  select dateadd(day, 1, C.D)
  from C
  where C.D < datefromparts(@Year, 12, 31)
)
select datepart(iso_week, C.D) as ISOWeekNo,
       convert(varchar(101), min(C.D), 106)+' To '+convert(varchar(101), max(C.D), 106) as WeekName
from C
group by datepart(iso_week, C.D),
         case when datepart(month, C.D) = 12 and
                   datepart(iso_week, C.D) > 50
           then 1
           else 0 
         end
order by min(C.D)
option (maxrecursion 0);

結果:

ISOWeekNo   WeekName
----------- --------------------------
53          01 Jan 2016 To 03 Jan 2016
1           04 Jan 2016 To 10 Jan 2016
2           11 Jan 2016 To 17 Jan 2016
3           18 Jan 2016 To 24 Jan 2016
4           25 Jan 2016 To 31 Jan 2016
5           01 Feb 2016 To 07 Feb 2016
6           08 Feb 2016 To 14 Feb 2016
7           15 Feb 2016 To 21 Feb 2016
.
.
.
47          21 Nov 2016 To 27 Nov 2016
48          28 Nov 2016 To 04 Dec 2016
49          05 Dec 2016 To 11 Dec 2016
50          12 Dec 2016 To 18 Dec 2016
51          19 Dec 2016 To 25 Dec 2016
52          26 Dec 2016 To 31 Dec 2016
于 2013-01-03T06:33:34.680 に答える
0

これは役立つかもしれません:

Select date '2012-12-31' + level*7                WK_STARTS_DT
 , to_char(date '2012-12-31' + level*7, 'IW') ISO_WEEK
 , to_char(date '2012-12-31' + level*7, 'WW') WEEK
From dual
Connect By Level <= 
(
 Select Round( (ADD_MONTHS(TRUNC(SYSDATE,'Y'),12)-TRUNC(SYSDATE,'Y') )/7, 0) From dual
) --365/7 
/

WK_STARTS_DT    ISO_WEEK    WEEK
------------------------------------
1/7/2013             02    01
1/14/2013            03    02
1/21/2013            04    03
......
2/4/2013             06    05
2/11/2013            07    06
......
3/4/2013             10    09

週番号を確認するには: http://www.epochconverter.com/date-and-time/weeknumbers-by-year.php?year=2013

于 2013-01-03T22:09:50.290 に答える