先週の金曜日の日付を取得するための正しいSQLコードを取得しようとしています。数日前、自分のコードは正しいと思いました。しかし、先週の金曜日ではなく、先週の金曜日の日付になっていることに気づきました。私がこの質問を書いている日は、土曜日、8/11/2012 @ 12:23 amです。 SQL Serverでは、このコードは2012年8月3日金曜日を返します。ただし、代わりに2012年8月10日金曜日にこれを返します。このコードを修正するにはどうすればよいですか?ここでは詳細を説明しているので、現在の日付が金曜日の場合、今日の日付を返します。したがって、昨日(2012年8月10日)で、このコードを昨日実行した場合、このコードは2012年8月3日ではなく2012年8月10日を返します。
SELECT DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()), 0))
これを試して:
declare @date datetime;
set @date='2012-08-09'
SELECT case when datepart(weekday, @date) >5 then
DATEADD(DAY, +4, DATEADD(WEEK, DATEDIFF(WEEK, 0, @date), 0))
else DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, @date), 0)) end
結果:
2012-08-03
例2:
declare @date datetime;
set @date='2012-08-10'
SELECT case when datepart(weekday, @date) >5 then
DATEADD(DAY, +4, DATEADD(WEEK, DATEDIFF(WEEK, 0, @date), 0))
else DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, @date), 0)) end
結果:
2012-08-10
モジュラー演算は最も直接的なアプローチであり、演算の順序によって金曜日の処理方法が決まります。
DECLARE @test_date DATETIME = '2012-09-28'
SELECT DATEADD(d,-1-(DATEPART(dw,@test_date) % 7),@test_date) AS Last_Friday
,DATEADD(d,-(DATEPART(dw,@test_date+1) % 7),@test_date) AS This_Friday
これを使って :
SELECT DATEADD(day, (DATEDIFF (day, '19800104', CURRENT_TIMESTAMP) / 7) * 7, '19800104') as Last_Friday
@@ DATEFIRSTの設定に関係なく機能するテスト済み関数。
-- ==============
-- fn_Get_Week_Ending_forDate
-- Author: Shawn C. Teague
-- Create date: 2017
-- Modified date:
-- Description: Returns the Week Ending Date on DayOfWeek for a given stop date
-- Parameters: DayOfWeek varchar(10) i.e. Monday,Tues,Wed,Friday,Sat,Su,1-7
-- DateInWeek DATE
-- ==============
CREATE FUNCTION [dbo].[fn_Get_Week_Ending_forDate] (
@DayOfWeek VARCHAR(10),@DateInWeek DATE)
RETURNS DATE
AS
BEGIN
DECLARE @End_Date DATE
,@DoW TINYINT
SET @DoW = CASE WHEN ISNUMERIC(@DayOfWeek) = 1
THEN CAST(@DayOfWeek AS TINYINT)
WHEN @DayOfWeek like 'Su%' THEN 1
WHEN @DayOfWeek like 'M%' THEN 2
WHEN @DayOfWeek like 'Tu%' THEN 3
WHEN @DayOfWeek like 'W%' THEN 4
WHEN @DayOfWeek like 'Th%' THEN 5
WHEN @DayOfWeek like 'F%' THEN 6
ELSE 7
END
select @End_Date =
CAST(DATEADD(DAY,
CASE WHEN (@DoW - (((@@datefirst) + datepart(weekday, @DateInWeek)) % 7)) = 7
THEN 0
WHEN (@DoW - (((@@datefirst) + datepart(weekday, @DateInWeek)) % 7)) < 0
THEN 7 - ABS(@DoW - (((@@datefirst) + datepart(weekday, @DateInWeek)) % 7))
ELSE (@DoW - (((@@datefirst) + datepart(weekday, @DateInWeek)) % 7) )
END
,@DateInWeek) AS DATE)
RETURN @End_Date
END
そのどれも?これを試して:
DECLARE @D DATE = GETDATE()
SELECT DATEADD(D,-(DATEPART(W,@D)+1)%7,@D)
先週の金曜日になります。
SELECT DATEADD(day, -3 - (DATEPART(dw, GETDATE()) + @@DATEFIRST - 2) % 7, GETDATE()) AS LastWeekFriday
これにより、先週の金曜日の日付がわかります。
SELECT DATEADD(day, +4 - (DATEPART(dw, GETDATE()) + @@DATEFIRST-2) % 7, GETDATE()) AS LastFriday
SELECT DECODE(TO_CHAR(SYSDATE,'DY'),'FRI',SYSDATE,NEXT_DAY(SYSDATE, 'FRI')-7) FROM dual;
次のコードは、@ dw_wkを置き換えることにより、任意の最終日を返すために使用できます。以下のテストケースは、元の質問で尋ねられた金曜日を使用します
DECLARE @date SMALLDATETIME
,@dw_wk INT --last day of week required - its integer representation
,@dw_day int --current day integer reprsentation
SELECT @date='8/11/2012'
SELECT @dw_day=DATEPART(dw,@date)
SELECT @dw_wk=DATEPART(dw,'1/2/2015') --Just trying not to hard code 5 for friday, here we can substitute with any date which is friday
SELECT case when @dw_day<@dw_wk then DATEADD(DAY, @dw_wk-7-@dw_day,@date) else DATEADD(DAY,@dw_wk-@dw_day, @date) END
これが私が見つけた答えです here MySQLからT-SQLに適応したもので、すべての基本的な計算(除算やモジュロなし)を使用する1つのライナーです:
SELECT DATEADD(d, 1 - datepart(weekday, dateadd(d, 2, GETDATE())), GETDATE())
コマンドの1と2のリテラルを変更するだけで、今日が金曜日でない限り次の金曜日の日付を取得したり、今日が木曜日でない場合は最後の木曜日の日付を取得したりするなど、あらゆる種類の組み合わせを実行できます。
今日が金曜日でない限り、次の金曜日の日付を取得します
SELECT DATEADD(d, 7 - datepart(weekday, dateadd(d, 1, GETDATE())), GETDATE())
今日が木曜日でない限り、最後の木曜日の日付を取得します
SELECT DATEADD(d, 1 - datepart(weekday, dateadd(d, 3, GETDATE())), GETDATE())
私はこれと同じ問題を抱えており、次の例を作成してこれを行う方法を示し、希望する曜日に柔軟に使用できるようにしています。 SELECT
ステートメントに別の行があります。これは何をしているのかを示すためだけですが、[Results]
答えを得るための行。また、現在の日付と目標の曜日の変数を使用して、何を変更する必要があるかを簡単に確認できるようにしました。
最後に、考えられる例として現在の日付を含めたい場合、または常に前の週に戻りたい場合の結果の例があります。
DECLARE @GetDate AS DATETIME = GETDATE();
DECLARE @Target INT = 6 -- 6 = Friday
SELECT
@GetDate AS [Current Date] ,
DATEPART(dw, @GetDate) AS [Current Day of Week],
@Target AS [Target Day of Week] ,
IIF(@Target = DATEPART(dw, @GetDate), 'Yes' , 'No') AS [IsMatch] ,
IIF(@Target = DATEPART(dw, @GetDate), 0 , ((7 + @Target - DATEPART(dw, @GetDate)) % 7) - 7) AS [DateAdjust] ,
------------------------------------------------------------------------------------------------------------------------------------------------
CAST(IIF(@Target = DATEPART(dw, @GetDate), @GetDate, DATEADD(d, (((7 + @Target - DATEPART(dw, @GetDate)) % 7) - 7), @GetDate)) AS DATE) AS [Result]
------------------------------------------------------------------------------------------------------------------------------------------------
;
SELECT
@GetDate AS [Current Date] ,
DATEPART(dw, @GetDate) AS [Current Day of Week],
@Target AS [Target Day of Week] ,
((7 + @Target - DATEPART(dw, @GetDate)) % 7) - 7 AS [DateAdjust] ,
------------------------------------------------------------------------------------------------------------------------------------------------
CAST(DATEADD(d, (((7 + @Target - DATEPART(dw, @GetDate)) % 7) - 7), @GetDate) AS DATE) AS [NOTIncludeCurrent]
------------------------------------------------------------------------------------------------------------------------------------------------
;
select convert(varchar(10),dateadd(d, -((datepart(weekday, getdate()) + 1 + @@DATEFIRST) % 7), getdate()),101)