Come si ottiene la “settimana di inizio” e la “settimana di fine” dal numero della settimana in SQL Server?

Ho una query che conta le date del matrimonio del membro nel database …

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 

Come faccio a capire quando l’inizio e la fine di ogni settimana sono rappresentati nel set di risultati?

 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 

Puoi trovare il giorno della settimana e aggiungere una data in giorni per ottenere le date di inizio e fine ..

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

Probabilmente vorresti anche spogliare il tempo dalla data.

Ecco una soluzione agnostica DATEFIRST :

 SET DATEFIRST 4 /* or use any other weird value to test it */ DECLARE @d DATETIME SET @d = GETDATE() SELECT @d ThatDate, DATEADD(dd, (@@DATEFIRST + 5 + DATEPART(dw, @d)) % 7, @d) Monday, DATEADD(dd, 6 - (@@DATEFIRST + 5 + DATEPART(dw, @d)) % 7, @d) Sunday 

puoi anche usare questo:

  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 

Ecco un’altra versione. Se il tuo scenario richiede che sabato sia il 1 ° giorno della settimana e il venerdì sia l’ultimo giorno della settimana, il codice seguente gestirà quanto segue:

  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 della query

La query sottostante fornirà i dati tra l’inizio e la fine della settimana corrente a partire da domenica a sabato

 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()) 

Espansione sulla risposta di @ Tomalak . La formula funziona per giorni diversi da domenica e lunedì, ma è necessario utilizzare valori diversi per dove si trova il 5. Un modo per arrivare al valore che ti serve è

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

ecco un link al documento: https://msdn.microsoft.com/en-us/library/ms181598.aspx

Ed ecco un tavolo che lo espone per te.

  | 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 

Ma non è necessario ricordare quella tabella e solo la formula, e in realtà si potrebbe usare una leggermente diversa anche la necessità principale è quella di usare un valore che faccia il resto il numero corretto di giorni.

Ecco un esempio funzionante:

 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 

Questo metodo sarebbe agnostico dell’impostazione DATEFIRST che è ciò di cui avevo bisogno poiché sto costruendo una dimensione di data con metodi di più settimane inclusi.

Cerchiamo di rompere il problema in due parti:

1) Determina il giorno della settimana

DATEPART(dw, ...) restituisce un numero, 1 … 7, relativo all’impostazione DATEFIRST ( documenti ). La seguente tabella riassume i possibili valori:

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

L’ultima colonna contiene il valore del giorno della settimana ideale per le settimane da lunedì a domenica *. Solo guardando il grafico arriviamo alla seguente equazione:

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

2) Calcola il lunedì e la domenica per una determinata data

Questo è banale grazie al valore del giorno della settimana. Ecco un esempio:

 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 

Produzione:

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

* Per le settimane da domenica a sabato è necessario regolare l’equazione un po ‘, come aggiungere 1 da qualche parte.

Ho appena incontrato un caso simile con questo, ma la soluzione qui sembra non aiutarmi. Quindi provo a capirlo da solo. Io lavoro fuori solo la settimana, la data di fine settimana dovrebbe essere di logica simile.

 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 

La risposta più votata funziona bene tranne che per la 1a settimana e l’ultima settimana di un anno. Ad esempio, se il valore di WeddingDate è “2016-01-01”, il risultato sarà il 2015-12-27 e il 2016-01-02 , ma la risposta corretta è il 01-01-2016 e il 2016-01-02 .

Prova questo:

 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; 

Il risultato è simile a: inserisci la descrizione dell'immagine qui

Funziona per tutte le settimane, 1 ° o altri.

Questo non è venuto da me, ma ha fatto il lavoro:

 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 

L’ho trovato qui .

Non sono sicuro di quanto sia utile, ma sono finito qui cercando una soluzione su Netezza SQL e non sono riuscito a trovarne uno in overflow dello stack.

Per IBM netezza useresti qualcosa (per week start lun, week end sun) come:

selezionare next_day (WeddingDate, ‘SUN’) -6 come WeekStart,

next_day (WeddingDate, ‘SUN’) come WeekEnd

per le query di accesso, è ansible utilizzare nel formato seguente come campo

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

Calcolo diretto consentito ..