Holen Sie sich das Wochenstartdatum und das Wochenenddatum aus der Wochennummer


98

Ich habe eine Abfrage, die die Hochzeitsdaten der Mitglieder in der Datenbank zählt.

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

Wie arbeite ich aus, wenn der Beginn und das Ende jeder Woche in der Ergebnismenge dargestellt werden?

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

Antworten:


161

Sie können den Wochentag finden und an Tagen ein Datum hinzufügen, um das Start- und Enddatum zu erhalten.

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

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

Sie möchten wahrscheinlich auch die Zeit vom Datum entfernen.


3
Denken Sie daran, dass die Einstellung DATEFIRSTauf etwas anderes als 7 dies unterbricht.
Tomalak

5
Es wird es nicht "brechen", es wird datefirst verwenden, um WeekStart = auf das zu setzen, was DateFirst als ersten Tag einer Woche angibt. Ihre Version wird immer Montag und Sonntag als Anfang und Ende einer Woche ausführen, nicht das, was der Server als Anfang und Ende der Woche verwenden soll
Robin Day

1
Hm ... Das ist ein gültiger Punkt, +1. :) Ich werde meine dann löschen (obwohl es ein Schuss in den Fuß war, war es sehr gut ausgerichtet. G ).
Tomalak

1
Nun, dann lösche ich es wieder. Ich bin mir nicht sicher, wer bei klarem Verstand sowieso etwas anderes als Montag als Wochenbeginn annehmen würde. Um die Woche zu beginnen am Sonntag keinen Sinn macht , was auch immer . :-)
Tomalak

3
'set datefirst 1' für Montag ( msdn.microsoft.com/en-ie/library/ms181598.aspx )
Selrac

41

Hier ist eine DATEFIRSTagnostische Lösung:

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
Das ist großartig, aber der Montag hat bei mir nicht funktioniert. Ich musste "0 -" hinzufügen, um Montag zu bekommen. Mein Montag-Code lautet jetzt: DATEADD (dd, 0 - (@@ DATEFIRST + 5 + DATEPART (dw, @d))% 7, @d)
Warren

Hat sowohl die Antwort als auch den Kommentar von Warrens positiv bewertet. SQL Server Version 11.0.5058.0 gibt mindestens das falsche Datum für Montag ohne Warrens-Änderung an. Gab mir stattdessen Freitag.
Morvael

18

Sie können dies auch verwenden:

  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

Erweiterung der Antwort von @ Tomalak . Die Formel funktioniert für andere Tage als Sonntag und Montag, aber Sie müssen unterschiedliche Werte für die 5 verwenden. Ein Weg, um zu dem Wert zu gelangen, den Sie benötigen, ist

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

Hier ist ein Link zum Dokument: https://msdn.microsoft.com/en-us/library/ms181598.aspx

Und hier ist ein Tisch, der es für Sie auslegt.

          | 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

Aber Sie müssen sich nicht an diese Tabelle und nur an die Formel erinnern, und tatsächlich könnten Sie auch eine etwas andere verwenden. Das Hauptbedürfnis besteht darin, einen Wert zu verwenden, der den Rest auf die richtige Anzahl von Tagen bringt.

Hier ist ein Arbeitsbeispiel:

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

Diese Methode ist unabhängig von der DATEFIRSTEinstellung, die ich brauchte, um eine Datumsdimension mit mehrwöchigen Methoden zu erstellen.


2

Hier ist eine andere Version. Wenn in Ihrem Szenario der Samstag der erste Wochentag und der Freitag der letzte Wochentag sein muss, wird dies mit dem folgenden Code behandelt:

  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

Screenshot der Abfrage


1

Die folgende Abfrage enthält Daten zwischen Beginn und Ende der aktuellen Woche von Sonntag bis Samstag

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

Lassen Sie uns das Problem in zwei Teile aufteilen:

1) Bestimmen Sie den Wochentag

Das DATEPART(dw, ...)gibt eine Zahl von 1 ... 7 relativ zur DATEFIRSTEinstellung ( docs ) zurück. Die folgende Tabelle fasst die möglichen Werte zusammen:

                                                   @@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  |
+------------------------------------+-----+-----+-----+-----+-----+-----+-----+-----+

Die letzte Spalte enthält den idealen Wochentagswert für die Wochen von Montag bis Sonntag *. Wenn wir uns nur das Diagramm ansehen, erhalten wir die folgende Gleichung:

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

2) Berechnen Sie den Montag und Sonntag für ein bestimmtes Datum

Dies ist dank des Wochentagswerts trivial. Hier ist ein Beispiel:

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

Ausgabe:

+------------------+------------------+------------------+
|  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  |
+------------------+------------------+------------------+

* Für Wochen von Sonntag bis Samstag müssen Sie die Gleichung nur ein wenig anpassen, z. B. irgendwo 1 hinzufügen.


1

Wenn der Sonntag als Wochenstarttag betrachtet wird, ist hier der Code

Declare @currentdate date = '18 Jun 2020'

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

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

0

Ich stoße gerade auf einen ähnlichen Fall mit diesem, aber die Lösung hier scheint mir nicht zu helfen. Also versuche ich es selbst herauszufinden. Ich arbeite nur das Startdatum der Woche aus, das Enddatum der Woche sollte von ähnlicher Logik sein.

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

Die am häufigsten gewählte Antwort funktioniert gut, mit Ausnahme der ersten Woche und der letzten Woche eines Jahres. Wenn der Wert von WeddingDate beispielsweise "2016-01-01" ist, lautet das Ergebnis 2015-12-27 und 2016-01-02 , aber die richtige Antwort lautet 2016-01-01 und 2016-01-02 .

Versuche dies:

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;

Das Ergebnis sieht aus wie: Geben Sie hier die Bildbeschreibung ein

Es funktioniert für alle Wochen, 1. oder andere.


0

Das kam nicht von mir, aber es hat die Arbeit erledigt:

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

Ich habe es hier gefunden .


0

Start- und Enddatum der Woche ab Datum für Power BI Dax Formula

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

0

Das ist meine Lösung

    SET DATEFIRST 1; / * ändern, um zuerst ein anderes Datum zu verwenden * /
    DECLARE @date DATETIME
    SET @date = CAST ('06.02.2019' als Datum)

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


0

Startdatum und Enddatum nach benutzerdefiniertem Datum abrufen


   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]


Während dieser Code die Frage lösen kann, hilft das Hinzufügen einer Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern.
Shree

0

Ich habe einen anderen Weg, es ist Tag Start und Tag Ende der Woche Aktuell ausgewählt:

DATEADD (d, - (DATEPART (dw, GETDATE () - 2)), GETDATE ()) ist Datum und Uhrzeit Start

und

DATEADD (Tag, 7- (DATEPART (dw, GETDATE () - 1)), GETDATE ()) ist Datum Uhrzeit Ende


0

Ein anderer Weg, es zu tun:

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)

Erläuterung:

  • @week_number ist die Wochennummer seit dem ersten Kalenderdatum ' 1900-01-01 '. Es kann folgendermaßen berechnet werden:select datediff(week, 0, @wedding_date) as week_number
  • @start_weekday für den ersten Tag der Woche: 0 für Montag, -1 Sonntag
  • @end_weekday für die Woche am letzten Tag: 6 für den nächsten Sonntag, 5 für den Samstag
  • dateadd(week, @week_number, @end_weekday): fügt die angegebene Anzahl von Wochen und die angegebene Anzahl von Tagen zum ursprünglichen Kalenderdatum ' 1900-01-01 ' hinzu

-3

Ich bin mir nicht sicher, wie nützlich dies ist, aber ich habe hier nach einer Lösung für Netezza SQL gesucht und konnte keine Lösung für den Stapelüberlauf finden.

Für IBM Netezza würden Sie etwas verwenden (für Wochenbeginn Mo, Wochenendsonne) wie:

Wählen Sie next_day (WeddingDate, 'SUN') -6 als WeekStart.

next_day (WeddingDate, 'SUN') als WeekEnd


-4

Für Zugriffsabfragen können Sie das folgende Format als Feld verwenden

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

direkte Berechnung erlaubt ..

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.