我似乎在詢問很多SQL問題。 (我通常會寫一個程序來對數據進行排序到報告表,但是在那是不可能的時刻,並且需要使用SQL來完成)SQL - WHERE子句在下一個工作日返回結果
問題 我需要返回結果的where子句下一個工作日。即01/01/01週一,下一個工作日將是02/01/01的星期二,這可以通過簡單的日期添加來實現。然而在05/01/01的星期五,下一個工作日是08/01/01星期一。是否有內置的東西可以幫助輕鬆應對?
感謝您的建議。
我似乎在詢問很多SQL問題。 (我通常會寫一個程序來對數據進行排序到報告表,但是在那是不可能的時刻,並且需要使用SQL來完成)SQL - WHERE子句在下一個工作日返回結果
問題 我需要返回結果的where子句下一個工作日。即01/01/01週一,下一個工作日將是02/01/01的星期二,這可以通過簡單的日期添加來實現。然而在05/01/01的星期五,下一個工作日是08/01/01星期一。是否有內置的東西可以幫助輕鬆應對?
感謝您的建議。
你可以用一個簡單的一天檢查做到這一點,加3幾天而不是一個,如果它是一個星期五。不過,你是否需要考慮公衆假期?
關鍵是要使用DATEPART(weekday,@date)函數,它將返回星期幾,所以如果是星期六或星期日,只需在當前日期中添加一到兩個即可獲得所需結果。
您可以創建用戶定義函數這樣做很容易,例如Pinal Dave有這個
CREATE FUNCTION dbo.udf_GetPrevNextWorkDay (@dtDate DATETIME, @strPrevNext VARCHAR(10))
RETURNS DATETIME
AS
BEGIN
DECLARE @intDay INT
DECLARE @rtResult DATETIME
SET @intDay = DATEPART(weekday,@dtDate)
--To find Previous working day
IF @strPrevNext = 'Previous'
IF @intDay = 1
SET @rtResult = DATEADD(d,-2,@dtDate)
ELSE
IF @intDay = 2
SET @rtResult = DATEADD(d,-3,@dtDate)
ELSE
SET @rtResult = DATEADD(d,-1,@dtDate)
--To find Next working day
ELSE
IF @strPrevNext = 'Next'
IF @intDay = 6
SET @rtResult = DATEADD(d,3,@dtDate)
ELSE
IF @intDay = 7
SET @rtResult = DATEADD(d,2,@dtDate)
ELSE
SET @rtResult = DATEADD(d,1,@dtDate)
--Default case returns date passed to function
ELSE
SET @rtResult = @dtDate
RETURN @rtResult
END
GO
你可以用一個簡單的case語句來做到這一點。
select case when datepart(dw, getdate()) >= 6 then getdate() + (9 - datepart(dw, getdate())) else getdate() + 1 end
CREATE FUNCTION dbo.uf_GetNextWorkingDay (@givenDate DATETIME)
RETURNS DATETIME
AS
BEGIN
DECLARE @workingDate DATETIME
IF (DATENAME(dw , @givenDate) = 'Friday')
BEGIN
SET @workingDate = DATEADD(day, 3, @givenDate)
END
ELSE IF (DATENAME(dw , @givenDate) = 'Saturday')
BEGIN
SET @workingDate = DATEADD(day, 2, @givenDate)
END
ELSE
BEGIN
SET @workingDate = DATEADD(day, 1, @givenDate)
END
RETURN @workingDate
END
一篇好文章http://ryanfarley.com/blog/archive/2005/02/14/1685.aspx
你需要的是一個日曆表。如果你需要考慮週末以外的其他假期,那麼下一個工作日就不那麼簡單了。該表基本上只包含兩列Date和一個整數字段,指示它是否爲工作/非工作日 - 但也可以有其他列,例如四分之一等。
此表每年填充一次,然後根據需要進行維護。獲得下一個工作日的結果就像這樣的查詢一樣簡單。
SELECT field1,filed2 from your table T where your date_Field = (SELECT min(date) From calendar table where WorkingDay = 1 and date > GetDate())
/P
這個怎麼樣事端?
select * from table
where (date = dateadd(dd,1,@today) and datepart(weekday,@today) not in (6,0)) --its not friday or saturday
or (date = dateadd(dd,2,@today) and datepart(weekday,@today) = 0) -- its saturday
or (date = dateadd(dd,3,@today) and datepart(weekday,@today) = 6) --its friday
日期屬性應該有相同的時間@Today否則你必須
所有信貸之間也使用Cashif - 我修改了他對包括假期表(tblHolidays
與日期字段HolDate
),它非常輕便 - 如果你足夠幸運,可以每年大約10行!
我的版本返回date
類型(我發現它更容易處理)。我也不止一次地運行 - 如果星期四是你的開始日,星期五是假期,那麼你必須再增加2天才能到達星期一(或下一個工作日)。然後檢查以確保下一週不會從假期開始。
CREATE FUNCTION [dbo].[GetNextWorkingDay] (@givenDate DATE)
RETURNS DATE
AS
BEGIN
DECLARE @workingDate DATETIME
IF (DATENAME(dw , @givenDate) = 'Friday')
BEGIN
SET @workingDate = DATEADD(day, 3, @givenDate)
END
ELSE IF (DATENAME(dw , @givenDate) = 'Saturday')
BEGIN
SET @workingDate = DATEADD(day, 2, @givenDate)
END
ELSE
BEGIN
SET @workingDate = DATEADD(day, 1, @givenDate)
END
while ((Select count(*) from tblHolidays where holdate = @workingDate) > 0)
begin
set @workingDate = dateadd(dd,1,@WorkingDate)
end
-- if adding a day makes it a Saturday, add 2 more to get to Monday (and test to make sure the week doesn't start with a holiday)
IF (DATENAME(dw , @workingDate) = 'Saturday')
BEGIN
SET @workingDate = DATEADD(day, 2, @workingDate)
END
while ((Select count(*) from tblHolidays where holdate = @workingDate) > 0)
begin
set @workingDate = dateadd(dd,1,@WorkingDate)
end
RETURN @workingDate
END
...當然你應該重構所以代碼不重複,幷包括一個while子句重複只需要多次,以達到一個工作日,但我有一個截止日期......這將是另一個更少忙碌的一天。
這裏就是我做了一個一次性的應用程序:
WHILE EXISTS (SELECT * FROM Holidays WHERE CONVERT(VARCHAR, HolidayDate,101) = CONVERT(VARCHAR,@DateVariable 101) OR DATENAME(WEEKDAY, @DateVariable)='SATURDAY' OR DATENAME(WEEKDAY, @DateVariable)='SUNDAY')
BEGIN
SET @DateVariable = DateAdd(day,1,@DateVariable)
PRINT @DateVariable -- If you want
END
需要注意的是,我們的Holidays
表存儲了所有節假日,在過去和今後幾年。
我很喜歡這個。漂亮,簡單而優雅 – user853710 2016-04-06 12:41:51
上面已經基本回答了,但花了我一段時間纔得到它,我想也許這會幫助別人。使用簡單的CASE-WHEN。
這是一個檢查,以找出哪些天是工作日
DATEPART(dw, date) -> MON through FRI = 1,2,3,4,5 SAT = 6, SUN = 7
這種情況下,WHEN:
CASE
WHEN DATEPART(weekday, date) <= 5 THEN date -- weekdays, no change
WHEN DATEPART(weekday, date) = 6 THEN date + 2 -- SAT + 2 = MON
WHEN DATEPART(weekday, date) = 6 THEN date + 1 -- SUN + 1 = MON
END AS 'WEEKDAY_DATES'
檢查,如果語句實際上只讓你平日:
CASE
WHEN DATEPART(weekday, date) <= 5 THEN DATENAME(weekday, date)
WHEN DATEPART(weekday, date) = 6 THEN DATENAME(weekday, date + 2)
WHEN DATEPART(weekday, date) = 6 THEN DATENAME(weekday, date + 1)
END AS 'WEEKDAY_NAMES'
理想情況下是,但如果它太複雜,那不是重要。 – Audioillity 2009-08-18 12:04:07
具有固定日期的簡單PublicHolidays表將很容易選擇;展開@ Pinal的UDF(來自@ Vinko的回答),以便爲每場比賽將日期加1(無論朝哪個方向)。更詳細的假期設計可能是不必要的。 – devstuff 2009-08-18 12:15:29
當我第一次想到時,它的簡單得多,報告只在週一天運行/創建。所以我需要做的就是制定出如果星期五加3天,否則我加1。 – Audioillity 2009-08-19 13:29:52