Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
查找特定日期为“的星期五”;“最近的”;在T-Sql中使用_Sql_Sql Server - Fatal编程技术网

查找特定日期为“的星期五”;“最近的”;在T-Sql中使用

查找特定日期为“的星期五”;“最近的”;在T-Sql中使用,sql,sql-server,Sql,Sql Server,我正在寻找一种优雅简单的方法来确定最接近某个特定日期的星期五的日期。有什么想法吗?这将返回未来最接近的星期五: SELECT DATEADD(day, 6 - (DATEDIFF(day, '01/01/2010', @mydate) - 1) % 7, @mydate) 你必须滑动一周的开始时间(使用DATEFIRST),这样你就可以把星期二变成一周的中间时间,然后你只需将天数加到最近的星期五 SET NOCOUNT ON SET DATEFIRST 3 Declare @DateVal

我正在寻找一种优雅简单的方法来确定最接近某个特定日期的星期五的日期。有什么想法吗?

这将返回未来最接近的星期五:

SELECT  DATEADD(day, 6 - (DATEDIFF(day, '01/01/2010', @mydate) - 1) % 7, @mydate)

你必须滑动一周的开始时间(使用
DATEFIRST
),这样你就可以把星期二变成一周的中间时间,然后你只需将天数加到最近的星期五

SET NOCOUNT ON
SET DATEFIRST 3

Declare @DateValue DateTime

SET @DateValue = '1/1/2010'

While @DateValue < '2/1/2011'
BEGIN
    PRINT DateAdd (Day, 3 - DatePart (dw, @DateValue), @DateValue)
    SET @DateValue = @DateValue + 1
END
将NOCOUNT设置为ON
将日期设置为3
声明@DateValue日期时间
设置@DateValue='1/1/2010'
而@DateValue<'2/1/2011'
开始
打印日期添加(日期,3-DatePart(dw,@DateValue),@DateValue)
设置@DateValue=@DateValue+1
结束

如果您需要查找最近(过去或未来)的星期五,请尝试以下方法:

DECLARE @StartDate datetime
       ,@EndDate   datetime
       ,@BeforeDate   datetime


SET @StartDate='2010-3-1'---<<<given date, Monday, closest should be '2010-2-26'
SET @EndDate=@StartDate+8
SET @BeforeDate=@StartDate-8
;with AllDates AS
(
    SELECT @StartDate AS DateOf, 1 as TypeOf,DATENAME(weekday,@StartDate) AS WeekDayOf, ABS(DATEDIFF(day,@StartDate,@StartDate)) AS DifferenceOf
    UNION ALL
    SELECT DateOf+1 AS DateOf,2 AS TypeOf,DATENAME(weekday,DateOf+1 ) AS WeekDayOf, ABS(DATEDIFF(day,@StartDate,DateOf+1)) AS DifferenceOf
        FROM AllDates
    WHERE DateOf<@EndDate-1 AND TypeOf IN (1,2)
    UNION ALL
    SELECT DateOf-1 AS DateOf,3 AS TypeOf,DATENAME(weekday,DateOf-1 ) AS WeekDayOf, ABS(DATEDIFF(day,@StartDate,DateOf-1)) AS DifferenceOf
        FROM AllDates
    WHERE DateOf>@BeforeDate-1 AND TypeOf IN (1,3)
)
SELECT TOP 1 DateOf
    FROM AllDates
    WHERE WeekDayOf='Friday'
    ORDER BY DifferenceOf

诀窍是确定离提供日期最近的星期五还有多少天。要提供帮助,请查看一整周以及离最近的星期五还有多少天:

星期日-2
星期一-3日
星期二3
星期三2
星期四1
星期五0
星期六-1

现在需要一个公式来返回这些结果。因为星期日和星期一与一周中的其他日子遵循不同的模式,所以需要两个公式

首先,这是星期天和星期一的。它将周值加1,然后将负数应用于日期添加。例如,星期一的默认值为“星期几”。(2 + 1) * -1 = -3. -3+星期一=星期五

星期二到星期六使用类似的算法:日期返回星期几的值3、4、5、6和7。我们需要分别为3,2,1,0,-1添加日期值。得到这个的公式是DW*-1+6

DECLARE @Date AS datetime
SET @Date = '3/1/2010'
SELECT
    CASE
        WHEN DATEPART(dw, @Date) <= 2
        THEN DATEADD(d, -1 * (DATEPART(dw, @Date) + 1), @Date)
        ELSE DATEADD(d, DATEPART(dw, @Date) * -1 + 6, @Date)
    END AS NearestFriday
将@Date声明为datetime
设置日期='2010年3月1日'
挑选
案例

当DATEPART(dw,@Date)SQLServer解决方案作为用户定义函数时。不只是到最近的星期五,而是到您指定的任何工作日(1-7)中最近的一个:

CREATE FUNCTION RoundToNearestWeekday (
--Give this function a date, and the number of the weekday you want to round to the nearest of
    @DateInput date,   --Date you want to round
    @ToWeekdayNumber tinyint   --1 = round to nearest Sunday, 2 = round to nearest Monday, etc.
)
RETURNS date
AS
    BEGIN
        DECLARE @Offset tinyint, @LowNumber smallint, @HighNumber smallint, @NewDate date
        SET @Offset = (@ToWeekdayNumber + 3)%7
        SET @LowNumber = @Offset-3
        SET @HighNumber = @Offset+4
        SET @NewDate = dateadd(day,CASE WHEN datepart(weekday,@DateInput) <= @Offset THEN @LowNumber ELSE @HighNumber END - datepart(weekday,@DateInput),@DateInput)
        RETURN @NewDate
    END
创建函数RoundToNearestWeekday(
--为该函数指定一个日期,以及要四舍五入的工作日数
@DateInput date,--要舍入的日期
@ToWeekdayNumber tinyint--1=四舍五入到最近的星期天,2=四舍五入到最近的星期一,以此类推。
)
返回日期
作为
开始
声明@Offset tinyint、@LowNumber smallint、@HighNumber smallint、@NewDate
设置偏移量=(@ToWeekdayNumber+3)%7
设置@LowNumber=@Offset-3
设置@HighNumber=@Offset+4

设置@NewDate=dateadd(日期,datepart时的大小写)(工作日,@DateInput)为我们定义最近的日期,可能是的。星期六比星期三近吗?你能解释一下日期文字2010年1月1日的用法吗?它是任意的还是需要定期更新?我在循环中运行了一个日期范围,我认为它返回下一个星期五,而不是最近的一个(可能是过去的),如果你在2010-03-01(今天)运行它的话它发现2010-03-05不是最近的,也就是2010-2-26@Jeremy:此文字是星期五。您可以将其替换为任何您想要的星期五。在我看来,此方法有效,但有以下更改:SET-NOCOUNT ON SET-DATEFIRST 2 Declare@DateValue-DateTime SET@DateValue='1/1/2010'而@DateValue<'2/1/2011'开始打印DateAdd(Day,4-DatePart(dw,@DateValue),@DateValue)SET@DateValue=@DateValue+1 End正如我前面提到的,这很好地工作,并“舍入”到最近的星期五(向上或向下),但您必须进行以下更改:…SET DATEFIRST 3…PRINT DateAdd(Day,4-DatePart…这是一个很好的答案,感谢您的解释和解决方案
CREATE FUNCTION RoundToNearestWeekday (
--Give this function a date, and the number of the weekday you want to round to the nearest of
    @DateInput date,   --Date you want to round
    @ToWeekdayNumber tinyint   --1 = round to nearest Sunday, 2 = round to nearest Monday, etc.
)
RETURNS date
AS
    BEGIN
        DECLARE @Offset tinyint, @LowNumber smallint, @HighNumber smallint, @NewDate date
        SET @Offset = (@ToWeekdayNumber + 3)%7
        SET @LowNumber = @Offset-3
        SET @HighNumber = @Offset+4
        SET @NewDate = dateadd(day,CASE WHEN datepart(weekday,@DateInput) <= @Offset THEN @LowNumber ELSE @HighNumber END - datepart(weekday,@DateInput),@DateInput)
        RETURN @NewDate
    END