週番号から週の開始日と終了日を取得する


98

データベースにメンバーの結婚式の日付をカウントするクエリがあります。

SELECT 
  SUM(NumberOfBrides) AS [Wedding Count]
  , DATEPART( wk, WeddingDate) AS [Week Number]
  , DATEPART( year, WeddingDate) AS [Year]
FROM  MemberWeddingDates
GROUP BY DATEPART(year, WeddingDate), DATEPART(wk, WeddingDate)
ORDER BY SUM(NumberOfBrides) DESC

毎週の初めと終わりが結果セットに含まれる場合、どのように計算しますか?

SELECT
  SUM(NumberOfBrides) AS [Wedding Count]
  , DATEPART(wk, WeddingDate) AS [Week Number]
  , DATEPART(year, WeddingDate) AS [Year]
  , ??? AS WeekStart
  , ??? AS WeekEnd
FROM  MemberWeddingDates
GROUP BY DATEPART(year, WeddingDate), DATEPART(wk, WeddingDate)
ORDER BY SUM(NumberOfBrides) DESC

回答:


161

曜日を見つけて、日付を追加し、開始日と終了日を取得できます。

DATEADD(dd, -(DATEPART(dw, WeddingDate)-1), WeddingDate) [WeekStart]

DATEADD(dd, 7-(DATEPART(dw, WeddingDate)), WeddingDate) [WeekEnd]

また、日付から時間を取り除いた方がよいでしょう。


3
DATEFIRST7以外に設定すると、これが壊れることを覚えておいてください。
トマラック2009

5
これは「分割」されず、datefirstを使用してWeekStart =を、DateFirstが週の最初の日とする日付に設定します。バージョンは常に月曜日と日曜日を週の初めと終わりとして実行します。サーバーが週の初めと終わりとして使用するように設定されているものではありません
Robin Day

1
うーん...それは有効なポイントです、+ 1。:)私はそれから削除します(足で撃たれたので、それは非常によく狙われていました。g)。
Tomalak 2009

1
さて、それから私はそれを元に戻します。とにかく、誰が正しい心の中で、月曜日以外のことを週の始まりとみなすのかはわかりません。週を日曜日に開始することは、まったく意味がありません。:-)
トマラック2009

3
月曜日の 'set datefirst 1'(msdn.microsoft.com/en-ie/library/ms181598.aspx
Selrac

41

これはDATEFIRST不可知論的なソリューションです:

SET DATEFIRST 4     /* or use any other weird value to test it */
DECLARE @d DATETIME

SET @d = GETDATE()

SELECT
  @d ThatDate,
  DATEADD(dd, 0 - (@@DATEFIRST + 5 + DATEPART(dw, @d)) % 7, @d) Monday,
  DATEADD(dd, 6 - (@@DATEFIRST + 5 + DATEPART(dw, @d)) % 7, @d) Sunday

11
これは素晴らしいことですが、月曜日は私にとってうまくいきませんでした。月曜日を取得するには、「0-」を追加する必要がありました。私の月曜日コードは今です:DATEADD(dd、0-(@@ DATEFIRST + 5 + DATEPART(dw、@d))%7、@d)
Warren

回答とウォーレンズのコメントの両方に賛成した。SQL Serverバージョン11.0.5058.0では、少なくとも月曜日の日付が間違っており、ウォーレンズを変更していません。代わりに金曜日をくれた。
Morvael

18

これを使用することもできます:

  SELECT DATEADD(day, DATEDIFF(day, 0, WeddingDate) /7*7, 0) AS weekstart,
         DATEADD(day, DATEDIFF(day, 6, WeddingDate-1) /7*7 + 7, 6) AS WeekEnd

2

@Tomalakの答えを拡張します。この式は日曜日と月曜日以外の日でも機能しますが、5がどこにあるかには異なる値を使用する必要があります。必要な価値に到達する方法は

Value Needed = 7 - (Value From Date First Documentation for Desired Day Of Week) - 1

ここにドキュメントへのリンクがあります:https : //msdn.microsoft.com/en-us/library/ms181598.aspx

そして、ここにあなたのためにそれをレイアウトするテーブルがあります。

          | DATEFIRST VALUE |   Formula Value   |   7 - DATEFIRSTVALUE - 1
Monday    | 1               |          5        |   7 - 1- 1 = 5
Tuesday   | 2               |          4        |   7 - 2 - 1 = 4
Wednesday | 3               |          3        |   7 - 3 - 1 = 3
Thursday  | 4               |          2        |   7 - 4 - 1 = 2
Friday    | 5               |          1        |   7 - 5 - 1 = 1
Saturday  | 6               |          0        |   7 - 6 - 1 = 0
Sunday    | 7               |         -1        |   7 - 7 - 1 = -1

ただし、そのテーブルと式だけを覚える必要はありません。実際には少し異なるテーブルを使用することもできますが、主な必要は、残りを正しい日数にする値を使用することです。

これが実際の例です:

DECLARE @MondayDateFirstValue INT = 1
DECLARE @FridayDateFirstValue INT = 5
DECLARE @TestDate DATE = GETDATE()

SET @MondayDateFirstValue = 7 - @MondayDateFirstValue - 1
SET @FridayDateFirstValue = 7 - @FridayDateFirstValue - 1

SET DATEFIRST 6 -- notice this is saturday

SELECT 
    DATEADD(DAY, 0 - (@@DATEFIRST + @MondayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate)  as MondayStartOfWeek
    ,DATEADD(DAY, 6 - (@@DATEFIRST + @MondayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate) as MondayEndOfWeek
   ,DATEADD(DAY, 0 - (@@DATEFIRST + @FridayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate)  as FridayStartOfWeek
    ,DATEADD(DAY, 6 - (@@DATEFIRST + @FridayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate) as FridayEndOfWeek


SET DATEFIRST 2 --notice this is tuesday

SELECT 
    DATEADD(DAY, 0 - (@@DATEFIRST + @MondayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate)  as MondayStartOfWeek
    ,DATEADD(DAY, 6 - (@@DATEFIRST + @MondayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate) as MondayEndOfWeek
   ,DATEADD(DAY, 0 - (@@DATEFIRST + @FridayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate)  as FridayStartOfWeek
    ,DATEADD(DAY, 6 - (@@DATEFIRST + @FridayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate) as FridayEndOfWeek

このメソッドはDATEFIRST、複数の週メソッドが含まれる日付ディメンションを構築するときに必要な設定にとらわれません。


2

これは別のバージョンです。シナリオで土曜日を週の最初の日とし、金曜日を週の最後の日とする必要がある場合、以下のコードで処理します。

  DECLARE @myDate DATE = GETDATE()
  SELECT    @myDate,
    DATENAME(WEEKDAY,@myDate),
    DATEADD(DD,-(CHOOSE(DATEPART(dw, @myDate), 1,2,3,4,5,6,0)),@myDate) AS WeekStartDate,
    DATEADD(DD,7-CHOOSE(DATEPART(dw, @myDate), 2,3,4,5,6,7,1),@myDate) AS WeekEndDate

クエリのスクリーンショット


1

以下のクエリは、日曜日から土曜日に始まり、現在の週の始めと終わりの間のデータを与えます

SELECT DOB FROM PROFILE_INFO WHERE DAY(DOB) BETWEEN
DAY( CURRENT_DATE() - (SELECT DAYOFWEEK(CURRENT_DATE())-1))
AND
DAY((CURRENT_DATE()+(7 - (SELECT DAYOFWEEK(CURRENT_DATE())) ) ))
AND
MONTH(DOB)=MONTH(CURRENT_DATE())

1

問題を2つの部分に分けましょう。

1)曜日を決定する

DATEPART(dw, ...)数、1 ... 7に対して返すDATEFIRST(設定ドキュメントを)。次の表は、可能な値をまとめたものです。

                                                   @@DATEFIRST
+------------------------------------+-----+-----+-----+-----+-----+-----+-----+-----+
|                                    |  1  |  2  |  3  |  4  |  5  |  6  |  7  | DOW |
+------------------------------------+-----+-----+-----+-----+-----+-----+-----+-----+
|  DATEPART(dw, /*Mon*/ '20010101')  |  1  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |
|  DATEPART(dw, /*Tue*/ '20010102')  |  2  |  1  |  7  |  6  |  5  |  4  |  3  |  2  |
|  DATEPART(dw, /*Wed*/ '20010103')  |  3  |  2  |  1  |  7  |  6  |  5  |  4  |  3  |
|  DATEPART(dw, /*Thu*/ '20010104')  |  4  |  3  |  2  |  1  |  7  |  6  |  5  |  4  |
|  DATEPART(dw, /*Fri*/ '20010105')  |  5  |  4  |  3  |  2  |  1  |  7  |  6  |  5  |
|  DATEPART(dw, /*Sat*/ '20010106')  |  6  |  5  |  4  |  3  |  2  |  1  |  7  |  6  |
|  DATEPART(dw, /*Sun*/ '20010107')  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |  7  |
+------------------------------------+-----+-----+-----+-----+-----+-----+-----+-----+

最後の列には、月曜日から日曜日の週の理想的な曜日の値が含まれています*。チャートを見るだけで、次の方程式が得られます。

(@@DATEFIRST + DATEPART(dw, SomeDate) - 1 - 1) % 7 + 1

2)指定された日付の月曜日と日曜日を計算します

これは、曜日の値のおかげで簡単です。次に例を示します。

WITH TestData(SomeDate) AS (
    SELECT CAST('20001225' AS DATETIME) UNION ALL
    SELECT CAST('20001226' AS DATETIME) UNION ALL
    SELECT CAST('20001227' AS DATETIME) UNION ALL
    SELECT CAST('20001228' AS DATETIME) UNION ALL
    SELECT CAST('20001229' AS DATETIME) UNION ALL
    SELECT CAST('20001230' AS DATETIME) UNION ALL
    SELECT CAST('20001231' AS DATETIME) UNION ALL
    SELECT CAST('20010101' AS DATETIME) UNION ALL
    SELECT CAST('20010102' AS DATETIME) UNION ALL
    SELECT CAST('20010103' AS DATETIME) UNION ALL
    SELECT CAST('20010104' AS DATETIME) UNION ALL
    SELECT CAST('20010105' AS DATETIME) UNION ALL
    SELECT CAST('20010106' AS DATETIME) UNION ALL
    SELECT CAST('20010107' AS DATETIME) UNION ALL
    SELECT CAST('20010108' AS DATETIME) UNION ALL
    SELECT CAST('20010109' AS DATETIME) UNION ALL
    SELECT CAST('20010110' AS DATETIME) UNION ALL
    SELECT CAST('20010111' AS DATETIME) UNION ALL
    SELECT CAST('20010112' AS DATETIME) UNION ALL
    SELECT CAST('20010113' AS DATETIME) UNION ALL
    SELECT CAST('20010114' AS DATETIME)
), TestDataPlusDOW AS (
    SELECT SomeDate, (@@DATEFIRST + DATEPART(dw, SomeDate) - 1 - 1) % 7 + 1 AS DOW
    FROM TestData
)
SELECT
    FORMAT(SomeDate,                            'ddd yyyy-MM-dd') AS SomeDate,
    FORMAT(DATEADD(dd, -DOW + 1, SomeDate),     'ddd yyyy-MM-dd') AS [Monday],
    FORMAT(DATEADD(dd, -DOW + 1 + 6, SomeDate), 'ddd yyyy-MM-dd') AS [Sunday]
FROM TestDataPlusDOW

出力:

+------------------+------------------+------------------+
|  SomeDate        |  Monday          |    Sunday        |
+------------------+------------------+------------------+
|  Mon 2000-12-25  |  Mon 2000-12-25  |  Sun 2000-12-31  |
|  Tue 2000-12-26  |  Mon 2000-12-25  |  Sun 2000-12-31  |
|  Wed 2000-12-27  |  Mon 2000-12-25  |  Sun 2000-12-31  |
|  Thu 2000-12-28  |  Mon 2000-12-25  |  Sun 2000-12-31  |
|  Fri 2000-12-29  |  Mon 2000-12-25  |  Sun 2000-12-31  |
|  Sat 2000-12-30  |  Mon 2000-12-25  |  Sun 2000-12-31  |
|  Sun 2000-12-31  |  Mon 2000-12-25  |  Sun 2000-12-31  |
|  Mon 2001-01-01  |  Mon 2001-01-01  |  Sun 2001-01-07  |
|  Tue 2001-01-02  |  Mon 2001-01-01  |  Sun 2001-01-07  |
|  Wed 2001-01-03  |  Mon 2001-01-01  |  Sun 2001-01-07  |
|  Thu 2001-01-04  |  Mon 2001-01-01  |  Sun 2001-01-07  |
|  Fri 2001-01-05  |  Mon 2001-01-01  |  Sun 2001-01-07  |
|  Sat 2001-01-06  |  Mon 2001-01-01  |  Sun 2001-01-07  |
|  Sun 2001-01-07  |  Mon 2001-01-01  |  Sun 2001-01-07  |
|  Mon 2001-01-08  |  Mon 2001-01-08  |  Sun 2001-01-14  |
|  Tue 2001-01-09  |  Mon 2001-01-08  |  Sun 2001-01-14  |
|  Wed 2001-01-10  |  Mon 2001-01-08  |  Sun 2001-01-14  |
|  Thu 2001-01-11  |  Mon 2001-01-08  |  Sun 2001-01-14  |
|  Fri 2001-01-12  |  Mon 2001-01-08  |  Sun 2001-01-14  |
|  Sat 2001-01-13  |  Mon 2001-01-08  |  Sun 2001-01-14  |
|  Sun 2001-01-14  |  Mon 2001-01-08  |  Sun 2001-01-14  |
+------------------+------------------+------------------+

*日曜日から土曜日の週では、どこかに1を加えるなど、方程式を少しだけ調整する必要があります。


1

日曜日を週の開始日と見なす場合、ここにコードがあります

Declare @currentdate date = '18 Jun 2020'

select DATEADD(D, -(DATEPART(WEEKDAY, @currentdate) - 1), @currentdate)

select DATEADD(D, (7 - DATEPART(WEEKDAY, @currentdate)), @currentdate)

0

私はこれと同様のケースに遭遇しましたが、ここでの解決策は私を助けていないようです。だから私は自分でそれを理解しようとします。私は週の開始日のみを計算します。週の終了日も同様のロジックである必要があります。

Select 
      Sum(NumberOfBrides) As [Wedding Count], 
      DATEPART( wk, WeddingDate) as [Week Number],
      DATEPART( year, WeddingDate) as [Year],
      DATEADD(DAY, 1 - DATEPART(WEEKDAY, dateadd(wk, DATEPART( wk, WeddingDate)-1,  DATEADD(yy,DATEPART( year, WeddingDate)-1900,0))), dateadd(wk, DATEPART( wk, WeddingDate)-1, DATEADD(yy,DATEPART( year, WeddingDate)-1900,0))) as [Week Start]

FROM  MemberWeddingDates
Group By DATEPART( year, WeddingDate), DATEPART( wk, WeddingDate)
Order By Sum(NumberOfBrides) Desc

0

最も投票された回答は、年の第1週と最終週を除いて正常に機能します。たとえば、WeddingDateの値が「2016-01-01」の場合、結果は2015-12-272016-01-02になりますが、正しい答えは2016-01-012016-01-02です。

これを試して:

Select 
  Sum(NumberOfBrides) As [Wedding Count], 
  DATEPART( wk, WeddingDate) as [Week Number],
  DATEPART( year, WeddingDate) as [Year],
  MAX(CASE WHEN DATEPART(WEEK, WeddingDate) = 1 THEN CAST(DATEADD(YEAR, DATEDIFF(YEAR, 0, WeddingDate), 0) AS date) ELSE DATEADD(DAY, 7 * DATEPART(WEEK, WeddingDate), DATEADD(DAY, -(DATEPART(WEEKDAY, DATEADD(YEAR, DATEDIFF(YEAR, 0, WeddingDate), 0)) + 6), DATEADD(YEAR, DATEDIFF(YEAR, 0, WeddingDate), 0))) END) as WeekStart,
  MAX(CASE WHEN DATEPART(WEEK, WeddingDate) = DATEPART(WEEK, DATEADD(DAY, -1, DATEADD(YEAR, DATEDIFF(YEAR, 0, WeddingDate) + 1, 0))) THEN DATEADD(DAY, -1, DATEADD(YEAR, DATEDIFF(YEAR, 0, WeddingDate) + 1, 0)) ELSE DATEADD(DAY, 7 * DATEPART(WEEK, WeddingDate) + 6, DATEADD(DAY, -(DATEPART(WEEKDAY, DATEADD(YEAR, DATEDIFF(YEAR, 0, WeddingDate), 0)) + 6), DATEADD(YEAR, DATEDIFF(YEAR, 0, WeddingDate), 0))) END) as WeekEnd
FROM  MemberWeddingDates
Group By DATEPART( year, WeddingDate), DATEPART( wk, WeddingDate)
Order By Sum(NumberOfBrides) Desc;

結果は次のようになります。 ここに画像の説明を入力してください

それはすべての週、1日または他のために動作します。


0

Power BI Dax Formulaの週の開始日と終了日

WeekStartDate = [DateColumn] - (WEEKDAY([DateColumn])-1)
WeekEndDate = [DateColumn] + (7-WEEKDAY([DateColumn]))

0

これは私の解決策です

    日付を最初に設定1; / *最初に別の日付を使用するように変更* /
    DECLARE @date DATETIME
    SET @date = CAST( '2/6/2019' as date)

    SELECT DATEADD(dd、0-(DATEPART(dw、@date)-1)、@ date)[dateFrom]、 
            DATEADD(dd、6-(DATEPART(dw、@date)-1)、@ date)[dateTo]


0

カスタム日付で開始日と終了日を取得


   DECLARE @Date NVARCHAR(50)='05/19/2019' 
   SELECT
      DATEADD(DAY,CASE WHEN DATEPART(WEEKDAY, @Date)=1 THEN -6 ELSE 2 - DATEPART(WEEKDAY, @Date) END, CAST(@Date AS DATE)) [Week_Start_Date]
     ,DATEADD(DAY,CASE WHEN DATEPART(WEEKDAY, @Date)=1 THEN 0 ELSE  8 - DATEPART(WEEKDAY, @Date) END, CAST(@Date AS DATE)) [Week_End_Date]


このコードは問題を解決する可能性がありますが、説明を含めると、投稿の品質を向上させるのに役立ちます。
シュリー

0

私には他の方法があります、それは選択された曜日の開始と曜日の終わりです現在:

DATEADD(d、-(DATEPART(dw、GETDATE()-2))、GETDATE())は日付時刻です

そして

DATEADD(day、7-(DATEPART(dw、GETDATE()-1))、GETDATE())は日付時刻の終了です


0

それを行う別の方法:

declare @week_number int = 6280 -- 2020-05-07
declare @start_weekday int = 0 -- Monday
declare @end_weekday int = 6 -- next Sunday

select 
    dateadd(week, @week_number, @start_weekday), 
    dateadd(week, @week_number, @end_weekday)

説明:

  • @week_numberは、最初のカレンダー日付「1900-01-01」からの週番号です。次のように計算できます。select datediff(week, 0, @wedding_date) as week_number
  • 週の最初の日の@start_weekday:月曜日は0、日曜日は-1
  • 週の@end_weekday最後の日:6次の日曜日のため、5かの土曜日
  • dateadd(week, @week_number, @end_weekday):与えられた週数と与えられた日数を最初のカレンダー日付 ' 1900-01-01 'に追加します

0

これは私からのものではありませんが、関係なく仕事を完了しました:

SELECT DATEADD(wk, -1, DATEADD(DAY, 1-DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) --first day previous week
SELECT DATEADD(wk, 0, DATEADD(DAY, 1-DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) --first day current week
SELECT DATEADD(wk, 1, DATEADD(DAY, 1-DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) --first day next week

SELECT DATEADD(wk, 0, DATEADD(DAY, 0-DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) --last day previous week
SELECT DATEADD(wk, 1, DATEADD(DAY, 0-DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) --last day current week
SELECT DATEADD(wk, 2, DATEADD(DAY, 0-DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) --last day next week

ここで見つけ


-3

これがどれほど便利かわかりませんが、私はNetezza SQLの解決策を探していて、スタックオーバーフローで解決策を見つけることができませんでした。

IBM netezzaの場合、次のようなものを使用します(週の開始月、週の終了日)

WeekStartとしてnext_day(WeddingDate、 'SUN')-6を選択し、

next_day(WeddingDate、 'SUN')as WeekEnd


-4

アクセスクエリの場合、以下の形式でフィールドとして使用できます

"FirstDayofWeek:IIf(IsDate([ForwardedForActionDate]),CDate(Format([ForwardedForActionDate],"dd/mm/yyyy"))-(Weekday([ForwardedForActionDate])-1))"

直接計算が可能です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.