【问题标题】:Select date and time range when date and time are in two seperate columns当日期和时间在两个单独的列中时选择日期和时间范围
【发布时间】:2018-02-23 12:34:14
【问题描述】:

我正在开发一个数据库,其中日期和时间位于两个单独的列中,我的任务是显示两个日期和时间间隔之间的记录。

我进行了以下查询,但这两个日期只给了我从 10 到 12 的记录。我错过了第二天12点到10点的记录。

我怎样才能做到这一点?

SELECT 
 [guid], 
 [date], 
 [time], 
 [pos]
FROM
  SomeTable
WHERE 
  [guid] = '0Q8m48D_uHua6P0' 
  AND [date] >= '2017-09-12' 
  AND time >= '10:00' 
  AND [date] <= '2017-09-13' 
  AND time <= '12:00';

【问题讨论】:

  • 时间列的数据类型是什么?
  • 组合它们 -> 将它们转换为 DateTime -> 使用 BETWEEN 。如果您根据日期创建 where 子句,则应将完整的 DateTime 存储在其自己的列中,因为它更容易处理。
  • 我认为最好有一个新的计算列来连接日期和时间,以便您可以过滤新的日期时间列。
  • @sagi 我很想在这个特定的问题中学习铸造,请您举个例子。
  • 有关结合日期和时间以获得单个日期的示例,请参阅此问题 - How to combine date and time to datetime2 in SQL Server?

标签: sql-server tsql


【解决方案1】:

有一个开始和结束日期例外的条款:

SELECT [guid], [date], [time], [pos]
FROM [table]
WHERE [guid] = '0Q8m48D_uHua6P0' 
and [date] >= '2017-09-12' AND [time] >= iif([date] = '2017-09-12', '10:00', [time])
AND [date] <= '2017-09-13' AND [time] <= iif([date] = '2017-09-13', '12:00', [time]);

【讨论】:

  • @sagi 你能解释一下为什么吗?
  • 硬维护,容易出错。 (顺便说一句,这不是我的反对意见)
  • @sagi 这太模糊了,无法帮助我进行改进。
  • 这个答案将比其他答案表现更好(在撰写本文时),但在当前格式下它是不正确的。您正在排除每天最后一分钟的记录。将错过合并日期和时间为20170912 23:59:59 的内容。您需要将23:59:00 更改为23:59:59.99999999
  • 我在 10 分钟前删除了我的反对票,就在我向您展示我没有“拒绝”它的 1 分钟后,我没有这样做。让我们继续吧。
【解决方案2】:

您可以将列计算为DATETIME,然后对其进行过滤。

;with cte as (
    SELECT 
     [guid], 
     [date], 
     [time], 
     [pos],
     DT = cast([date] as datetime) + cast([time] as datetime)
    FROM
      SomeTable
    WHERE 
      [guid] = '0Q8m48D_uHua6P0'
)

select * 
from cte
where DT between '20170912 10:00' and '20170913 12:00'

【讨论】:

    【解决方案3】:

    这是一种方法

    SELECT 
    [guid], 
    [date], 
    [time], 
    [pos]
    FROM
     SomeTable
    WHERE 
     [guid] = '0Q8m48D_uHua6P0' 
    AND
    CAST   (
    CONVERT(Varchar(10), [date], 112) + ' ' +   
    CONVERT(Varchar(8), [time]) AS DateTime) Between '2017-09-12 10:00' 
    AND '2017-09-13 12:00'
    

    【讨论】:

      【解决方案4】:

      你当然可以将它们组合起来,然后使用BETWEEN进行过滤,像这样:

      SELECT 
       [guid], 
       [date], 
       [time], 
       [pos]
      FROM
        SomeTable
      WHERE [guid] = '0Q8m48D_uHua6P0' 
        AND (DATEADD(day, DATEDIFF(day,'19000101', [date]), CAST([time] AS DATETIME2(7)))) BETWEEN '2017-09-12 12:00:00.000' and '2017-09-12 12:00:00.000'
      

      ..但这是一个坏主意,因为您的条件有一个函数, 可能使查询优化器忽略您可能拥有的任何索引(因为这样的查询不是sargable

      因此,我将在您的表上创建一个名为 [Datetime] 的新持久计算列或任何对您有意义的内容,然后为其指定一个默认值:

      DATEADD(day, DATEDIFF(day,'19000101', [date]), CAST([time] AS DATETIME2(7))))
      

      那么你就可以编写如下查询:

      SELECT 
       [guid], 
       [date], 
       [time], 
       [pos]
      FROM
        SomeTable
      WHERE [guid] = '0Q8m48D_uHua6P0' 
        AND [Datetime] BETWEEN '2017-09-12 12:00:00.000' and '2017-09-12 12:00:00.000'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-14
        • 2018-03-03
        • 1970-01-01
        • 2017-12-30
        • 2012-04-12
        • 1970-01-01
        • 2022-11-02
        • 1970-01-01
        相关资源
        最近更新 更多