SQL Server:如何使用datediff排除周末?

时间:2018-03-26 18:05:27

标签: sql-server ssms datediff

我还在学习SQL,所以请记住这一点。我有一个查询返回特定范围的平均天数,尽管我的范围不包括周末和周期。假期。假期可能有点棘手,但如何从我的范围中排除周末?

例如,我有一个范围02-01-18到02-15-18,其中的datediff是14天,但我如何让SQL识别该范围内的哪些天是周末,以及他们是否将它们排除在外我的约会?

我的查询是

SELECT
    AVG(1.00 * DATEDIFF(DAY, xx, yy)) AS DayDiff
FROM 
    datebase1.dbo.table1
WHERE
    MONTH(datecompleted) = MONTH(DATEADD(month, -1, current_timestamp))
    AND YEAR(datecompleted) = YEAR(DATEADD(month, -1, current_timestamp))
    AND ApprovalRequiredFrom = 'pp'

我有一个我可以提供的日历,告诉我日期和当天的名字,但我想避免这样做。我希望能够从我的范围中排除周末以获得更准确的结果。

由于

2 个答案:

答案 0 :(得分:1)

要排除周末,您需要在比较日期(xxyy)中过滤星期六和星期日。为此,您可以将DATEPART函数与WEEKDAY参数一起使用。结果是从1到7的数字,表示它是星期几。

-- 2018-01-01 is a monday
SELECT DATEPART(WEEKDAY, '2018-01-01')
-- Result: 2

问题是不同的数据库配置的日期与值" 1"改变了,所以也许是星期几" 1"对于其他人来说意味着星期天,对于其要统一此信息,您可以使用SET DATEFIRST更改默认值。

SET DATEFIRST 1 -- 1: Monday, 7: Sunday

-- 2018-01-01 is a monday
SELECT DATEPART(WEEKDAY, '2018-01-01')
-- Result: 1

另一个与datefirst无关的解决方案是直接在表达式上使用@@DATEFIRST会话值。 @@DATEFIRST保存我们在SET DATEFIRST语句或数据库默认值上设置的值。请注意,结果是相同的,甚至更改DATEFIRST

SET DATEFIRST 7 -- 1: Sunday, 2: Monday

-- 2018-01-01 is a monday
SELECT (DATEPART(WEEKDAY, '2018-01-01') + @@DATEFIRST) % 7
-- Result: 2


SET DATEFIRST 1 -- 1: Monday, 7: Sunday

-- 2018-01-01 is a monday
SELECT (DATEPART(WEEKDAY, '2018-01-01') + @@DATEFIRST) % 7
-- Result: 2

对于您的示例,您需要过滤xxyy日期,而不是周末。将以下内容添加到WHERE子句中:

WHERE
    --...
    AND (DATEPART(WEEKDAY, xx) + @@DATEFIRST) % 7 NOT IN (0, 1)
    AND (DATEPART(WEEKDAY, yy) + @@DATEFIRST) % 7 NOT IN (0, 1)

答案 1 :(得分:0)

由于需要使用旧的MySQL 5.1服务器,因此才有机会尝试一种“数学”方法来计算否。 SAT / SUN减去:

注意:MySQL的“工作日”函数对于Mon返回0,对于SAT返回5,对于SUN返回6,因此您在下面的SQL中看到了一些不可思议的数字。与5和6。

示例:

select  floor((datediff (ed, st)+1) / 7)*2 /*complete week's weekends*/
        + case when floor((datediff (ed, st) +1) % 7) between 0 and 6 /*additional weekends besides complete weeks*/
                then case when weekday(ed) >= weekday(st) then least(floor((datediff (ed, st) +1) % 7), greatest(least(6, weekday(ed)) - greatest(5, weekday(st)) + 1,0))
                                else least(floor((datediff (ed, st) +1) % 7), greatest(least(6, weekday(ed)+7) - greatest(5, weekday(st)) + 1,0)) end
            else 0
        end as num_of_sat_and_sun
from (select '2019-01-07' as st, '2019-01-12' as ed) x