Dapatkan tanggal mulai minggu dan tanggal akhir minggu dari nomor minggu


98

Saya memiliki kueri yang menghitung tanggal pernikahan anggota di 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

Bagaimana cara saya berolahraga ketika awal dan akhir setiap minggu terwakili dalam kumpulan hasil?

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

Jawaban:


161

Anda dapat menemukan hari dalam seminggu dan menambahkan tanggal pada hari untuk mendapatkan tanggal mulai dan berakhir ..

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

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

Anda mungkin juga ingin melihat stripping off waktu dari tanggal juga.


3
Ingatlah bahwa pengaturan DATEFIRSTke selain 7 mematahkan ini.
Tomalak

5
Itu tidak akan "merusak" itu, itu akan menggunakan datefirst untuk mengatur WeekStart = ke apa yang DateFirst katakan sebagai hari pertama dalam seminggu. Versi Anda akan selalu dilakukan pada hari Senin dan Minggu sebagai awal dan akhir minggu, bukan apa yang ditetapkan server untuk digunakan sebagai awal dan akhir minggu
Hari Robin

1
Hm ... Itu poin yang valid, +1. :) Saya akan menghapus milik saya, kemudian (Meskipun untuk ditembak di kaki, itu ditujukan dengan sangat baik. G ).
Tomalak

1
Nah, kemudian saya membatalkan penghapusan lagi. Saya tidak yakin siapa yang waras akan menganggap apa pun selain Senin sebagai awal minggu. Memulai minggu pada hari Minggu sama sekali tidak masuk akal . :-)
Tomalak

3
'set datefirst 1' untuk Senin ( msdn.microsoft.com/en-ie/library/ms181598.aspx )
Selrac

41

Berikut ini DATEFIRSTsolusi agnostik:

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
Ini bagus, tapi hari Senin tidak bekerja untuk saya. Saya harus menambahkan "0 -" untuk mendapatkan hari Senin. Kode Senin saya sekarang: DATEADD (hh, 0 - (@@ DATEFIRST + 5 + DATEPART (dw, @d))% 7, @d)
Warren

Memberikan suara positif untuk jawaban dan komentar Warrens. Sql Server Version 11.0.5058.0 setidaknya memberikan tanggal yang salah untuk hari Senin tanpa modifikasi Warrens. Memberiku hari Jumat sebagai gantinya.
Morvael

18

Anda juga bisa menggunakan ini:

  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

Memperluas jawaban @ Tomalak . Rumusnya berfungsi untuk hari selain Minggu dan Senin, tetapi Anda perlu menggunakan nilai yang berbeda untuk nilai 5. Cara untuk mencapai nilai yang Anda butuhkan adalah

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

berikut ini tautan ke dokumen: https://msdn.microsoft.com/en-us/library/ms181598.aspx

Dan berikut adalah tabel yang mengaturnya untuk Anda.

          | 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

Tetapi Anda tidak harus mengingat tabel itu dan hanya rumusnya, dan sebenarnya Anda juga dapat menggunakan tabel yang sedikit berbeda, kebutuhan utamanya adalah menggunakan nilai yang akan membuat sisanya menjadi jumlah hari yang benar.

Berikut adalah contoh yang berfungsi:

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

Metode ini akan menjadi agnostik dari DATEFIRSTPengaturan yang saya butuhkan saat saya membangun dimensi tanggal dengan metode beberapa minggu disertakan.


2

Ini versi lain. Jika Skenario Anda mengharuskan Sabtu menjadi hari pertama Minggu dan Jumat menjadi hari terakhir Minggu, kode di bawah ini akan menangani itu:

  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 dari Query


1

Query di bawah ini akan memberikan data antara awal dan akhir minggu ini mulai dari minggu hingga Sabtu

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

Mari kita pecahkan masalah menjadi dua bagian:

1) Tentukan hari dalam seminggu

The DATEPART(dw, ...)pengembalian sejumlah, 1 ... 7, relatif terhadap DATEFIRSTpengaturan ( docs ). Tabel berikut merangkum kemungkinan nilai:

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

Kolom terakhir berisi nilai hari-dalam-minggu yang ideal untuk Senin hingga Minggu minggu *. Dengan hanya melihat grafik kami mendapatkan persamaan berikut:

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

2) Hitung hari Senin dan Minggu untuk tanggal tertentu

Ini sepele berkat nilai hari dalam seminggu. Berikut ini contohnya:

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

Keluaran:

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

* Untuk minggu Minggu hingga Sabtu, Anda hanya perlu menyesuaikan persamaan sedikit, seperti menambahkan 1 di suatu tempat.


1

Jika hari Minggu dianggap sebagai hari mulai minggu, maka berikut kodenya

Declare @currentdate date = '18 Jun 2020'

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

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

0

Saya baru saja menemukan kasus serupa dengan yang ini, tetapi solusi di sini tampaknya tidak membantu saya. Jadi saya mencoba mencari tahu sendiri. Saya mengerjakan tanggal mulai minggu saja, tanggal akhir minggu harus memiliki logika yang sama.

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

Jawaban yang paling banyak dipilih berfungsi dengan baik kecuali untuk minggu pertama dan minggu terakhir dalam setahun. Misalnya, jika nilai WeddingDate adalah '2016/01/01', hasilnya akan 2015/12/27 dan 2016/01/02 , tetapi jawaban yang benar adalah 2016/01/01 dan 2016/01/02 .

Coba ini:

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;

Hasilnya terlihat seperti: masukkan deskripsi gambar di sini

Ini bekerja untuk semua minggu, pertama atau lainnya.


0

Minggu Mulai & Tanggal Berakhir Dari Tanggal Untuk Formula Power BI Dax

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

0

Ini solusi saya

    ATUR TANGGAL PERTAMA 1; / * ubah untuk menggunakan tanggal yang berbeda * /
    MENYATAKAN @tanggal DATETIME
    SET @date = CAST ('2/6/2019' sebagai tanggal)

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


0

Dapatkan Tanggal Mulai & Tanggal Berakhir dengan Tanggal Kustom


   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]


Meskipun kode ini dapat menyelesaikan pertanyaan, menyertakan penjelasan sangat membantu meningkatkan kualitas posting Anda.
Shree

0

Saya punya cara lain, itu pilih hari Awal dan hari Akhir Minggu Saat Ini:

DATEADD (d, - (DATEPART (dw, GETDATE () - 2)), GETDATE ()) adalah tanggal waktu Mulai

dan

DATEADD (hari, 7- (DATEPART (dw, GETDATE () - 1)), GETDATE ()) adalah tanggal waktu Berakhir


0

Cara lain untuk melakukannya:

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)

Penjelasan:

  • @week_number adalah nomor minggu sejak tanggal awal kalender ' 1900-01-01 '. Ini dapat dihitung dengan cara ini:select datediff(week, 0, @wedding_date) as week_number
  • @start_weekday untuk minggu hari pertama: 0 untuk Senin, -1 untuk Minggu
  • @end_weekday untuk minggu hari terakhir: 6 untuk Minggu depan, 5 jika Sabtu
  • dateadd(week, @week_number, @end_weekday): menambahkan jumlah minggu dan jumlah hari tertentu ke dalam tanggal awal kalender ' 1900-01-01 '

0

Ini tidak datang dari saya, tetapi menyelesaikan pekerjaan apa pun:

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

Saya menemukannya di sini .


-3

Tidak yakin seberapa berguna ini, tetapi saya berakhir di sini dari mencari solusi di Netezza SQL dan tidak dapat menemukannya di stack overflow.

Untuk IBM netezza Anda akan menggunakan sesuatu (untuk minggu mulai sen, minggu akhir minggu) seperti:

pilih next_day (WeddingDate, 'SUN') -6 sebagai WeekStart,

next_day (WeddingDate, 'SUN') sebagai WeekEnd


-4

untuk Access Queries, Anda bisa menggunakan format di bawah ini sebagai bidang

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

Penghitungan langsung diizinkan ..

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.