Hafta numarasından hafta başlangıç ​​tarihini ve hafta bitiş tarihini alın


99

Veritabanında üyenin düğün tarihlerini sayan bir sorgu var.

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

Sonuç kümesinde her haftanın başlangıcı ve sonu temsil edildiğinde nasıl çalışırım?

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

Yanıtlar:


164

Başlangıç ​​ve bitiş tarihlerini almak için haftanın gününü bulabilir ve günler ekleyebilirsiniz.

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

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

Muhtemelen aynı zamanda tarihten zamanın çıkarılmasına da bakmak istersiniz.


3
DATEFIRST7 dışında herhangi bir şeye ayarlamanın bunu kırdığını unutmayın.
Tomalak

5
Onu "kırmaz", datefirst'i WeekStart = değerini DateFirst'ün haftanın ilk gününün söylediği şeye ayarlamak için kullanır. Sürümünüz her zaman Pazartesi ve Pazar gününü haftanın başlangıcı ve sonu olarak yapacak, sunucunun haftanın başlangıcı ve sonu olarak kullanmak üzere ayarladığı şeyi değil
Robin Günü

1
Hm ... Bu geçerli bir nokta, +1. :) Benimkini sileceğim o zaman (Ayaktan vurulduğu için son derece iyi hedeflenmişti. G ).
Tomalak

1
O zaman tekrar silmeyi geri alırım. Zaten haftanın başlangıcı olarak pazartesiden başka bir şeyi aklı başında kimin varsayacağından emin değilim. Pazar hiçbir anlamı yapar haftayı başlatmak için olursa olsun . :-)
Tomalak

4
Pazartesi için "ilk tarih 1'i ayarla" ( msdn.microsoft.com/en-ie/library/ms181598.aspx )
Selrac

41

İşte DATEFIRSTagnostik bir çözüm:

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
Bu harika ama Pazartesi benim için çalışmıyordu. Pazartesi günleri almak için "0 -" eklemek zorunda kaldım. Pazartesi kodum şimdi: DATEADD (gg, 0 - (@@ DATEFIRST + 5 + DATEPART (dw, @d))% 7, @d)
Warren

Hem yanıta hem de Warren'ın yorumuna olumlu oy verdi. Sql Sunucu Sürümü 11.0.5058.0, en azından, Warrens değişikliği olmaksızın Pazartesi için yanlış tarih veriyor. Onun yerine bana Cuma veriyordu.
Morvael

18

bunu da kullanabilirsiniz:

  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

4

İşte başka bir versiyon. Senaryonuz Cumartesi gününün Haftanın 1. günü olmasını ve Cuma gününün Haftanın son günü olmasını gerektiriyorsa, aşağıdaki kod bunu halledecektir:

  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

Sorgunun ekran görüntüsü


2

@ Tomalak'ın cevabını genişletiyoruz . Formül, Pazar ve Pazartesi dışındaki günler için çalışır, ancak 5'in olduğu yer için farklı değerler kullanmanız gerekir. İhtiyacınız olan değere ulaşmanın bir yolu

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

işte belgeye bir bağlantı: https://msdn.microsoft.com/en-us/library/ms181598.aspx

Ve işte size onu düzenleyen bir masa.

          | 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

Ancak bu tabloyu ve sadece formülü hatırlamanız gerekmez ve aslında biraz farklı bir tane de kullanabilirsiniz, asıl ihtiyaç kalan kısmı doğru gün sayısı yapacak bir değer kullanmaktır.

İşte çalışan bir örnek:

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

Bu yöntem DATEFIRST, birden çok hafta yönteminin dahil olduğu bir tarih boyutu oluşturduğum için ihtiyacım olan Ayarın agnostiği olacaktır .


1

Aşağıdaki sorgu, pazar gününden cumartesiye kadar mevcut haftanın başlangıcı ve bitişi arasındaki verileri verecektir

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

Sorunu iki kısma ayıralım:

1) Haftanın gününü belirleyin

DATEPART(dw, ...)Döner bir sayı, 1 ... 7, göreli DATEFIRST(ayar docs ). Aşağıdaki tablo olası değerleri özetlemektedir:

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

Son sütun, pazartesiden pazara * hafta içi ideal haftanın günü değerini içerir . Sadece grafiğe bakarak aşağıdaki denklemi buluyoruz:

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

2) Verilen tarih için Pazartesi ve Pazar günlerini hesaplayın

Bu, haftanın günü değeri sayesinde önemsizdir. İşte bir örnek:

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

Çıktı:

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

* Pazardan cumartesiye haftalar için denklemi bir yere 1 eklemek gibi biraz ayarlamanız gerekir.


1

Pazar haftanın başlangıç ​​günü olarak kabul edilirse, işte kod

Declare @currentdate date = '18 Jun 2020'

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

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

0

Sadece bununla benzer bir durumla karşılaşıyorum, ancak buradaki çözüm bana yardımcı olmuyor gibi görünüyor. Bu yüzden kendim anlamaya çalışıyorum. Sadece hafta başlangıç ​​tarihini hesaplıyorum, hafta bitiş tarihi de benzer mantıkta olmalıdır.

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

En çok oylanan cevap, yılın 1. haftası ve son haftası dışında gayet iyi çalışıyor . Örneğin, WeddingDate değeri "2016-01-01" ise sonuç 2015-12-27 ve 2016-01-02 olur , ancak doğru yanıt 2016-01-01 ve 2016-01-02 olur .

Bunu dene:

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;

Sonuç şöyle görünür: görüntü açıklamasını buraya girin

1. veya diğerleri, tüm haftalar için çalışır.


0

Power BI Dax Formülü İçin Hafta Başlangıç ​​ve Bitiş Tarihi

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

0

Bu benim çözümüm

    TARİHİ İLK AYARLA 1; / * farklı bir ilk tarih kullanmak için değiştirin * /
    @Date DATETIME BİLDİR
    SET @date = CAST (tarih olarak '2/6/2019')

    TARİHİ SEÇİN (dd, 0 - (DATEPART (dw, @date) - 1), @ date) [dateFrom] 
            DATEADD (gg, 6 - (DATEPART (dw, @date) - 1), @ tarih) [dateTo]


0

Başlangıç ​​Tarihini ve Bitiş Tarihini Özel Tarihe Göre Alın


   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]


Bu kod soruyu çözebilirken, bir açıklama eklemek, gönderinizin kalitesini artırmanıza gerçekten yardımcı olur.
Shree

0

Başka bir yolum var, Gün Başlangıcı ve Hafta Sonu Geçerli Gün seçimidir:

DATEADD (d, - (DATEPART (dw, GETDATE () - 2)), GETDATE ()) tarih saattir Başlangıç

ve

DATEADD (gün, 7- (DATEPART (dw, GETDATE () - 1)), GETDATE ()) tarih zamanı Bitiş


0

Bunu yapmanın başka bir yolu:

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)

Açıklama:

  • @week_number, ilk takvim tarihi ' 1900-01-01'den itibaren olan hafta numarasıdır . Şu şekilde hesaplanabilir:select datediff(week, 0, @wedding_date) as week_number
  • Haftanın ilk günü için @start_weekday: Pazartesi için 0 , Pazar ise -1
  • Haftanın son günü için @end_weekday: sonraki Pazar için 6 , Cumartesi ise 5
  • dateadd(week, @week_number, @end_weekday): ' 1900-01-01 ' ilk takvim tarihine verilen hafta sayısını ve verilen gün sayısını ekler

0

Bu benden gelmiyor, ama ne olursa olsun işi halletti:

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

Burada buldum .


-3

Bunun ne kadar yararlı olduğundan emin değilim, ancak Netezza SQL'de bir çözüm aramaktan buraya geldim ve yığın taşması üzerinde bir çözüm bulamadım.

IBM netezza için aşağıdaki gibi bir şey kullanırsınız (hafta başı pazartesi, hafta sonu güneş için):

WeekStart olarak next_day (DüğünTarihi, 'SUN') -6'yı seçin,

next_day (WeddingDate, 'SUN') as WeekEnd


-4

Erişim Sorguları için aşağıdaki formatta alan olarak kullanabilirsiniz

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

doğrudan Hesaplamaya izin verilir ..

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.