2014-02-14 95 views
2

我有這個查詢拉最後一個星期五的日期與給定日期。除了如果給定的日期是今天以外,它全天都有效。拉最後一個星期五的日期

選擇DATEADD(d, - ((日期部分(星期,GETDATE())+ 1 + @@ DATEFIRST)% 7),GETDATE())

以例如,今天是2014年2月14日。如果我申請上面的查詢,返回的結果仍然是2014-02-14

dateadd(d, - ((datepart(weekday,'2014-02-14')+ 1 + @@ DATEFIRST) %7), '2014-02-14')

如果我把2014-02-13放在下面,那麼它會正確返回上個星期五的日期。

選擇DATEADD(d, - ((日期部分(星期, '2014年2月13日')+ 1 + @@ DATEFIRST)%7), '2014年2月13日')

你能幫助我如何得到上週五的日期,如果今天給出的是星期五。

+0

我猜這是[標籤:SQL服務器]? – Mureinik

+0

是的,我已經更新 – VeecoTech

回答

5

您可以檢查是否當前日期是週五DATENAME如果是這樣,只是減去7天,否則,使用你做

SELECT CASE WHEN DATENAME(WEEKDAY, GETDATE()) = 'Friday' THEN 
     CONVERT(DATE, DATEADD(DAY, -7, GETDATE())) 
    ELSE 
     DATEADD(d, -((DATEPART(WEEKDAY, GETDATE()) + 1 + @@DATEFIRST) % 7), GETDATE()) 
    END AS 'LastFriday' 
+0

如果語言設置不是英語?此外,使用[字符串文字作爲列別名](http://sqlblog.com/blogs/aaron_bertrand/archive/2012/01/23/bad-habits-to-kick-using-as-instead-of-for-column -aliases.aspx)已被棄用。這應該在任何新代碼中避免。 – GarethD

+0

感謝您的文章。和其他評論中的很多人一樣,我總是完成AS vs =。這將是非常艱難的打破習慣。 – TTeeple

+0

沒問題,我想'alias = column'與'column AS alias'完全相反,完全是個人偏好,我絕不會試圖強迫任何人使用另一個,但它是我能找到的最清晰的文章,證實'column AS'alias''已被棄用。它在[不推薦使用的列表](http://technet.microsoft.com/en-us/library/ms143729.aspx)的頁面上向下,因此不會立即清楚爲什麼我已將其鏈接。 – GarethD

3

如何蠻力方法:

select dateadd(day, 
       (case when datename(weekday, getdate()) = 'Friday' then -7 
        when datename(weekday, getdate()) = 'Saturday' then -1 
        when datename(weekday, getdate()) = 'Sunday' then -2 
        when datename(weekday, getdate()) = 'Monday' then -3 
        when datename(weekday, getdate()) = 'Tuesday' then -4 
        when datename(weekday, getdate()) = 'Wednesday' then -5 
        when datename(weekday, getdate()) = 'Thursday' then -6 
       end), 
       cast(getdate() as date) 
      ); 

這確實邏輯今天。您可以將所有getdate()引用替換爲其他日期的另一日期。

2

你的第一次嘗試似乎相當接近,我想你的功能只需要將1移到模函數的外部即可。這個工作對我來說:

SELECT DATEADD(DAY, -1 - ((DATEPART(WEEKDAY, GETDATE()) + @@DATEFIRST) % 7), CAST(GETDATE() AS DATE)); 

然後在一個更大的樣本測試,它似乎仍然工作:

DECLARE @T TABLE (DateFirst INT, Date DATE, LastFriday DATE) 
DECLARE @I INT = 1; 
WHILE @I < 8 
    BEGIN 

     SET DATEFIRST @i; 

     WITH TestDates AS 
     ( SELECT Date = DATEADD(DAY, -Number, CAST(GETDATE() AS DATE)) 
      FROM master..spt_values 
      WHERE Type = 'P' 
      AND  Number BETWEEN 0 AND 20 
     ) 
     INSERT @T (DateFirst, Date, lastFriday) 
     SELECT @I, 
       Date, 
       LastFriday = DATEADD(DAY, -1 - ((DATEPART(WEEKDAY, Date) + @@DATEFIRST) % 7), Date) 
     FROM TestDates; 

     SET @i += 1; 

    END 

SELECT * 
FROM @T 
     PIVOT 
     ( MAX(LastFriday) 
      FOR DateFirst IN ([1], [2], [3], [4], [5], [6], [7]) 
     ) pvt 
ORDER BY Date; 

這適用於所有的語言和DATEFIRST設置。

如果你能控制你的DATEFIRST設置這個變得更簡單:

SET DATEFIRST 6; 
SELECT DATEADD(DAY, -DATEPART(WEEKDAY, GETDATE()), CAST(GETDATE() AS DATE)) 

不過我總是建議讓您的查詢對本地設置安全。

相關問題