試験しました。 :-)
DECLARE @Date datetime = '01/11/2015'
DECLARE @StartDate datetime = DATEADD(d, (1 - (DATEDIFF(d, CAST('1899.12.31' AS datetime), @Date - 6) % 7)), @Date - 6) -- MONDAY
DECLARE @EndDate datetime = DATEADD(d, (5 - (DATEDIFF(d, CAST('1899.12.31' AS datetime), @Date - 6) % 7)), @Date - 6) -- FRIDAY
SELECT '@Date' as Variable ,CONVERT(date, @Date) as DateValue ,DATENAME(dw, @Date) as DayOfTheWeek
UNION SELECT '@StartDate' as Variable ,CONVERT(date, @StartDate) as DateValue ,DATENAME(dw, @StartDate) as DayOfTheWeek
UNION SELECT '@EndDate' as Variable ,CONVERT(date, @EndDate) as DateValue ,DATENAME(dw, @EndDate) as DayOfTheWeek
-- Variable DateValue DayOfTheWeek
-- ---------- ---------- ------------
-- @Date 2015-01-11 Sunday
-- @StartDate 2015-01-05 Monday
-- @EndDate 2015-01-09 Friday
BONUS:同じテクニックを使用して5つの平日のクイックテーブルを生成することができます。ここで
SELECT DATENAME(dw, DATEADD(d, TT.DaysToAdd, DATEADD(d, (1 - (DATEDIFF(d, CAST('1899.12.31' AS datetime), @Date - 6) % 7)), @Date - 6))) as DayOfTheWeek
, DATEADD(d, TT.DaysToAdd, DATEADD(d, (1 - (DATEDIFF(d, CAST('1899.12.31' AS datetime), @Date - 6) % 7)), @Date - 6)) as DateValue
FROM (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1 as DaysToAdd FROM (VALUES(0),(0),(0),(0),(0)) a(n)) as TT
-- DayOfTheWeek DateValue
-- ------------------------------ -----------------------
-- Monday 2015-01-05 00:00:00.000
-- Tuesday 2015-01-06 00:00:00.000
-- Wednesday 2015-01-07 00:00:00.000
-- Thursday 2015-01-08 00:00:00.000
-- Friday 2015-01-09 00:00:00.000
は説明です:
1)まず、私たちは私たちからの評価を開始するために何日かを知る必要があります。この例では、日付値
SELECT @Date2 as DateValue, DATENAME(dw, @Date2) as DayOfTheWeek
与えられ、ここで曜日の名前を取得するのボーナス技術を持っていてうれしいです)1月(日曜日)11日、2015年
DECLARE @Date2 datetime = '01/11/2015'
図1bを使用することにしました1899年12月31日は1900年1月1日前に最初の日曜日です:
2)次に、私たちは与えられた曜日が数値的には1〜7
- NOTEあるもの)米国のカレンダーに基づいて(確定知っておく必要がありますこれは最小値fまたはSmallDateTimeデータ型。
- 注:はい、あなたはもっと単純に、このようDATEPART(DW、@Date)を使用することができますが、それは特定のサーバ環境が異なる構成
結果かもしれないことを考えると、確定ではありません。1 =日曜日| 2 =月曜日| 3 =火曜日| 4 =水曜日| 5 =木曜日| 6 =金曜日| 7 =土曜日
SELECT ((DATEDIFF(d, CAST('1899.12.31' AS datetime), @Date2) % 7) + 1) [DayOfWeek Deterministic (Based on US)]
3)さて、任意の日付を考えると、あなたは、任意の日付与えられ、今では特定の週
SELECT DATEADD(d, (1 - (DATEDIFF(d, CAST('1899.12.31' AS datetime), @Date2) % 7)), @Date2) as [Monday Day of the Week - Deterministic (Based on US)]
4)のために月曜日を決定する決定論的な方法を持っている必要がありますあなたはその週の金曜日を決定する決定的な方法を持っているべきです
SELECT DATEADD(d, (5 - (DATEDIFF(d, CAST('1899.12.31' AS datetime), @Date2) % 7)), @Date2) as [Monday Day of the Week - Deterministic (Based on US)]
5)最後の日付操作技術それ以前に平日の最初の一週間がある週に入る方法を知る必要があります。例えば、もし私たちが日曜日にいて、それから1日を引くと、土曜日に到着します。これは前週になります。これは平日の最初の一週間です。また、月曜日から1日を差し引くと、それは先週ではない日曜日にしか私たちを得ることができないので、1日を引くだけでは不十分です。裏返して、もし我々が土曜日にあって7日を引いたならば、前週の曜日はそれより前の週になります。ここでは、魔法の数字が何かを引くことができるかを理解するために分析を実行します。あなたは以下を参照することができますように、マジックナンバーは6
-- DAYS TO SUBTRACT
-- Day of the Week - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7
-- =============== ==== ==== ==== ==== ==== ==== ==== ====
-- Sunday Bad Good Good Good Good Good Good Good
-- Monday Bad Bad Good Good Good Good Good Good
-- Tuesday Bad Bad Bad Good Good Good Good Good
-- Wednesday Bad Bad Bad Bad Good Good Good Good
-- Thursday Bad Bad Bad Bad Bad Good Good Good
-- Friday Bad Bad Bad Bad Bad Bad Good Good
-- Saturday Good Good Good Good Good Good Good Bad
BONUSあるあなたは少しテーブル内のすべての平日を持つようにしたい場合は)、あなたはまた、迅速なゼロベースの「集計表」を使用したいと思います。これを行うには多くの方法がありますので、あなたの味を選んでください。ここにはいくつかあります。
SELECT * FROM (SELECT 0 as DaysToAdd UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) as TT
SELECT * FROM (SELECT TOP 5 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1 as DaysToAdd FROM sys.all_columns a CROSS JOIN sys.all_columns b) as TT
SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1 as DaysToAdd FROM (VALUES(0),(0),(0),(0),(0)) a(n)) as TT
この質問はhttp://stackoverflow.com/questions/4025047/tsql-function-to-calculate-30-working-days-date-from-a-specified-date-sql-と非常によく似ていますサーバー –
@Brian Dishawはい、多分それはその質問のように見えますが、与えられたコードは本当に良くなく、答えは受け入れられませんでした。 Btw Faiz、6つの質問と答えがまだ受け入れられていません –