【问题标题】:Custom date range自定义日期范围
【发布时间】:2015-12-11 13:42:19
【问题描述】:

解释

有2个工作班次,白班=从07:00:0019:00:00和夜班=从19:00:0007:00:00


样本数据

Name    Date        Time        WorkShift
John    2015-09-14  19:14:24    N
John    2015-09-14  23:43:27    N
John    2015-09-15  03:21:36    N
John    2015-09-15  11:29:48    D

期望的结果

例如,我有 @dateStart = 2015-09-14@dateEnd = 2015-09-14 变量。我需要从2015-09-14 19:00:002015-09-15 07:00:00 中选择记录如下:

John    2015-09-14  19:14:24    N
John    2015-09-14  23:43:27    N
John    2015-09-15  03:21:36    N

如你所见,这里是日期2015-09-15,但Time03:21:36所以应该选择它(因为时间低于07:00:00N工作班次)。


问题

我的查询按预期选择,但有 2 个问题。

如果我通过 @dateStart = 2015-09-15@dateEnd = 2015-09-15 它选择:

John    2015-09-15  03:21:36    N -- this shouldn't be selected again, this should go as 2015-09-14 
John    2015-09-15  11:29:48    D 

另一个问题是,如果我有这样的记录

John    2015-09-15  03:21:36    N

如您所见,2015-09-14 中没有 John 的任何记录,所以当我在以下传递变量时应该选择它:@dateStart = 2015-09-15@dateEnd = 2015-09-15


查询

select *
from SampleTable
where /* Some conditions.... and*/
      (convert(date, StartTime) >= @dateStart) and
      (case when (DateCreated between cast(cast(cast(DateCreated as date) as varchar(40)) + ' 19:00:00' as datetime) 
                              and cast(cast(cast(DateCreated as date) as varchar(40)) + ' 23:59:59' as datetime)
                  or
                  DateCreated between cast(cast(cast(DateCreated as date) as varchar(40)) + ' 00:00:00' as datetime) 
                              and cast(cast(cast(DateCreated as date) as varchar(40)) + ' 07:00:00' as datetime)
                  )
                  and Workshift like '%N'
            then dateadd(day,-1,cast(cast(DateCreated as date) as varchar(40))) 
            else DateCreated
        end <= @dateEnd)

如果有什么不清楚的地方,可以问我,我会尽力解释。

【问题讨论】:

  • 有一次我在考勤登记程序中遇到类似的问题,我不得不使用时间戳和 AM/PM 并检查相同的问题来解决问题。我认为它可能对你有帮助。为什么你不要那样检查。
  • 有什么具体原因不采用 DATE 数据类型中的日期时间值并将其存储为 varchar 吗?
  • DATETIME 存储为varchar?如果是这样,不要那样做,这会变得容易容易
  • @Jamiec,不,它是 DATETIME 数据类型。
  • 那么为什么会有 2 个不同的字段呢? 都是日期时间吗?

标签: sql sql-server sql-server-2008 tsql date


【解决方案1】:

在开始和结束时间上增加小时怎么样?

where datetime >= dateadd(hour, 19, @datestart) and
      datetime < dateadd(hour, 7, @dateend)

如果您将“日期”和“时间”分别存储在不同的列中(一般不推荐),您可以在转换为datetime后添加它们:

where cast(date as datetime) + cast(time as datetime) >= dateadd(hour, 19, @datestart) and
      cast(date as datetime) + cast(time as datetime) < dateadd(hour, 7, @dateend)

【讨论】:

    【解决方案2】:

    试试这个

    select  *
    from SampleTable
    where convert(dateTime,DateCreated) + convert(dateTime,StartTime) 
    between DATEADD(HH,7, @dateStart) and DATEADD(HH,24+7, @dateEnd)
    or 
    (
        convert(dateTime,DateCreated) + convert(dateTime,StartTime) 
        between DATEADD(HH,00, @dateStart) and DATEADD(HH,7, @dateStart) -- Morning records
        and not exists 
            (
            select 1 from SampleTable where 
            convert(dateTime,DateCreated) + convert(dateTime,StartTime)  
            between DATEADD(HH,7-24, @dateStart) and DATEADD(HH,0, @dateStart)
            ) -- Data from previous day
    )
    

    【讨论】:

    • 感谢您的回答,但似乎是错误的。它返回相同的结果 14 天和相同的结果 15 天(如示例)
    • 知道了。对于每一天,您只需要白班和晚上......如果没有前一天的数据,您需要选择早上记录的行。更新解决方案
    • 谢谢,经过一些更正后看起来可以工作了。
    猜你喜欢
    • 1970-01-01
    • 2018-07-11
    • 2018-01-10
    • 1970-01-01
    • 2016-06-14
    • 2020-09-18
    • 1970-01-01
    • 1970-01-01
    • 2020-11-12
    相关资源
    最近更新 更多