【问题标题】:Removing weekends from a SQL result从 SQL 结果中删除周末
【发布时间】:2012-10-15 11:47:05
【问题描述】:

我有以下查询,它为我产生了许多结果。其中之一是每条记录的天数。

现在我需要一个更准确的数字,方法是从等式中删除周末。不知道如何继续并努力理解我找到的答案。到目前为止,我的查询是:

select
    i.incidentnumber,
    i.priority, 
    i.status, 
    i.subject,
    i.actualsystem, 
    t.ownerteam, 
    convert(varchar,i.createddatetime,103)[Created],
    convert(varchar,i.lastmoddatetime,103)[Modified], 
    datediff(day,i.createddatetime,{fn now()})[Days old],
    datediff(mi,i.createddatetime,{fn now()})[Minutes old],
    cast(i.createddatetime
    i.owner
from 
    incident i with (nolock) inner join task t with (nolock) on t.parentlink_recid = i.recid
where 
    i.status <> 'Closed' 
    and i.actualsystem <> 'System Administration' 
    --and i.service <> 'Service Request'
    and t.status in ('Active','Waiting','Accepted') 
    --and t.ownerteam <> 'UK Service Desk'

order by 
    --t.ownerteam asc
    --i.actualsystem asc
    datediff(day,i.createddatetime,{fn now()}) desc

我正在使用 SQL 服务器管理器并查询 2005 数据库。我根据需要注释掉。旧的分钟是今天添加的新列。有人可以帮忙吗?

【问题讨论】:

  • 周末只有周六和周日吗?假期呢?周五的假期是否被视为周末的一部分?假期是一般计算还是不计算?这个网站上已经有很多关于计算两个日期之间的天数的问题,最可靠的解决方案通常是calendar table,您可以简单地将天标记为工作日并编写简单的查询来获得答案。

标签: sql sql-server sql-server-2005 datediff


【解决方案1】:

DATEPART(dw, your_date) 会告诉你是否是周末。通常 1 表示星期六,7 表示星期日,但它可以根据服务器配置而改变。阅读 datepart 函数以了解其工作原理

【讨论】:

  • 其实1通常表示星期日,7=星期六,但逻辑是一样的。您可以使用 select @@DATEFIRST 找出您的服务器上的哪一天设置为 = 1。如果它有 7 则星期日 = 一周中的第一天。
  • 这有点令人困惑,因为@@DATEFIRST 函数应该返回一周的第一天,也就是星期日,但是 sunday 的值是 7,而不是你期望的 1。如果您查看此链接:msdn.microsoft.com/pt-br/library/ms181598.aspx,您会看到星期日意味着 7。
  • 谁说星期天是一周的第一天?很多人会告诉你今天是星期一。这就是为什么最好使用日期表而不是可能根据服务器设置返回不同结果的函数来处理与日期相关的任务的原因之一。
  • 使用 @@DATEFIRST 为您提供使用 Mon=1、Tue=2、Wed=3、Thu=4、Fri=5、Sat = 6 设置为一周的第一天的日期& Sun = 7。1 到 7 只是为了我们可以使用 smallint 而不是 varchar。这个值实际上告诉系统在 DATEPART(dw, date) 调用中一天将等于什么值。如果您将星期日设置为第 1 天,那么星期日现在将返回一个,因为这是您告诉系统回复的方式。
【解决方案2】:

如果您想计算该范围内的工作日(非周末)数,最简单的方法就是考虑每周 2 个周末。
例如:

SELECT Datediff(D, '2012-01-01', '2012-01-31') / 7 * 5 + 
              Datediff(D, '2012-01-01', '2012-01-31') % 7 WorkDays, 
       Datediff(D, '2012-01-01', '2012-01-31')            AllDays 

要计算工作时间(包括部分),请使用以下查询:

SELECT ( T.WORKDAYS - 1 ) * 10 + OPENINGDAYHOURS + CLOSINGDAYHOURS 
FROM   (SELECT Datediff(D, OPEN_DATE, CLOSE_DATE) / 7 * 5 + 
                              Datediff(D, OPEN_DATE, CLOSE_DATE) % 7 WorkDays, 
               18 - Datepart(HOUR, OPEN_DATE) 
               OpeningDayHours, 
               Datepart(HOUR, CLOSE_DATE) - 8 
               ClosingdayHours, 
               Datediff(D, OPEN_DATE, CLOSE_DATE)                    AllDays 
        FROM   TABLE1)T 

此查询假定工作日为上午 8 点到下午 6 点。

可以在here找到工作示例。

【讨论】:

  • 我想知道我是在一周的几天工作还是在一天的工作时间工作更好。后者听起来确实有点困难。
  • 为什么“营业时间”会更难?所有天的营业时间都相同,因此剩下的就是将天数乘以每天的小时数。
  • 因此,如果工作时间是每个工作日 10 小时,并且记录保持开放 281 天,那么我将如何计算不包括非工作时间的真实工作时间。例如营业时间是早上 8 点到下午 6 点。一个记录在下午 5 点开放,并保持开放 281 天。如何检索真实的营业时间?
  • 啊!您想计算全天 + 部分天(可能也在最后?)。我理解正确吗?如果是这样,我会尽快准备解决方案。
  • 是的,记录的天数考虑了周末和非工作时间的删除。抱歉所有问题,但这绝对有帮助。对我来说是一个巨大的学习曲线,但仍然有帮助
【解决方案3】:

为了安全起见,您需要从 DATEPART(dw,GETDATE()) 获取正确的数据

设置日期优先 1

它将确保 1 是星期一,7 - 是星期日。

参考: http://msdn.microsoft.com/en-en/library/ms181598.aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多