Neden Pazar günü değil de Pazartesi olduğunu yanıtlamak için:
0 tarihine birkaç hafta ekliyorsunuz. Tarih 0 nedir? 1900-01-01. 1900-01-01'de gün neydi? Pazartesi. Yani kodunuzda diyorsunuz ki, 1 Ocak 1900 Pazartesi'den bu yana kaç hafta geçti? Buna [n] diyelim. Tamam, şimdi 1 Ocak 1900 Pazartesi gününe [n] hafta ekleyin. Bunun Pazartesi olmasına şaşırmamalısınız. DATEADD
hafta eklemek istediğinizi bilmiyor ama sadece Pazar gününe gelene kadar, sadece 7 gün ekliyor, ardından 7 gün daha ekliyor ... tıpkı DATEDIFF
sadece aşılan sınırları tanıması gibi . Örneğin, bazıları yukarı veya aşağı yuvarlamak için yerleşik mantıklı bir mantık olması gerektiğinden şikayet etse de, bunların ikisi de 1 döndürür:
SELECT DATEDIFF(YEAR, '2010-01-01', '2011-12-31');
SELECT DATEDIFF(YEAR, '2010-12-31', '2011-01-01');
Pazar gününün nasıl alınacağını cevaplamak için:
Pazar günü istiyorsanız, Pazartesi değil Pazar olan bir temel tarih seçin. Örneğin:
DECLARE @dt DATE = '1905-01-01';
SELECT [start_of_week] = DATEADD(WEEK, DATEDIFF(WEEK, @dt, CURRENT_TIMESTAMP), @dt);
DATEFIRST
Geçerli ayardan bağımsız olarak Pazar günü olmasını istiyorsanız , ayarınızı değiştirirseniz (veya kodunuz farklı bir ayara sahip bir kullanıcı için çalışıyorsa) bu işlem bozulmayacaktır . Eğer jive için bu iki cevap istiyorsanız, o zaman bir işlevi kullanmalısınız gelmez bağlıdır DATEFIRST
ayarı, örneğin
SELECT DATEADD(DAY, 1-DATEPART(WEEKDAY, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP);
Yani, DATEFIRST
ayarınızı Pazartesi, Salı olarak değiştirirseniz, elinizde ne var, davranış değişecektir. Hangi davranışı istediğinize bağlı olarak şu işlevlerden birini kullanabilirsiniz:
CREATE FUNCTION dbo.StartOfWeek1
(
@d DATE
)
RETURNS DATE
AS
BEGIN
RETURN (SELECT DATEADD(WEEK, DATEDIFF(WEEK, '19050101', @d), '19050101'));
END
GO
...veya...
CREATE FUNCTION dbo.StartOfWeek2
(
@d DATE
)
RETURNS DATE
AS
BEGIN
RETURN (SELECT DATEADD(DAY, 1-DATEPART(WEEKDAY, @d), @d));
END
GO
Şimdi, birçok alternatifiniz var, ancak hangisi en iyi performansı gösteriyor? Herhangi bir büyük fark olursa şaşırırdım ama şimdiye kadar verilen tüm cevapları topladım ve bunları biri ucuz ve biri pahalı olmak üzere iki test setinden geçirdim. İstemci istatistiklerini ölçtüm çünkü burada G / Ç veya belleğin performansta bir rol oynadığını görmüyorum (ancak bunlar işlevin nasıl kullanıldığına bağlı olarak devreye girebilir). Testlerimde sonuçlar:
"Ucuz" atama sorgusu:
Function - client processing time / wait time on server replies / total exec time
Gandarez - 330/2029/2359 - 0:23.6
me datefirst - 329/2123/2452 - 0:24.5
me Sunday - 357/2158/2515 - 0:25.2
trailmax - 364/2160/2524 - 0:25.2
Curt - 424/2202/2626 - 0:26.3
"Pahalı" atama sorgusu:
Function - client processing time / wait time on server replies / total exec time
Curt - 1003/134158/135054 - 2:15
Gandarez - 957/142919/143876 - 2:24
me Sunday - 932/166817/165885 - 2:47
me datefirst - 939/171698/172637 - 2:53
trailmax - 958/173174/174132 - 2:54
İsterseniz testlerimin ayrıntılarını aktarabilirim - burada durarak bu zaten oldukça uzun sürüyor. Hesaplamaların sayısı ve satır içi kod göz önüne alındığında, Curt'ün en yüksek seviyede en hızlı çıktığını görmek beni biraz şaşırttı. Belki biraz daha kapsamlı testler yapacağım ve bununla ilgili blog yazacağım ... eğer fonksiyonlarınızı başka bir yerde yayınlamama itirazınız yoksa.
(@@DATEFIRST + DATEPART(DW, @SomeDate)) % 7
@@datefirst
bence ayar ne olursa olsun sabit kalır . Pazartesi ile = 2.