【问题标题】:calculating duration (Date - Date) from a case Expression从案例表达式计算持续时间(日期 - 日期)
【发布时间】:2017-05-26 10:29:28
【问题描述】:

我正在编写一个复杂的查询,但在从 case expression 计算时遇到了一些问题(谢谢)。基本上,多亏了这个网站上的一些巨大帮助,我设法通过使用有序表解决了另一个问题,但现在我以前使用的 select 语句之一不再适用于 OT。

我收到一个错误:

从字符串转换日期和/或时间时转换失败

问题的核心是我想通过从结束日期减去开始日期来计算持续时间。我之前使用的代码是

select
    cast((CASE 
             WHEN ap.startLIKE '%[^0-9]%' 
                THEN CAST(ap.end as datetime) 
                ELSE NULL 
          END)
          -
          (CASE 
              WHEN ap.start LIKE '%[^0-9]%' 
                 THEN CAST(ap.start as datetime) 
                 ELSE NULL 
           END) as time) as Duration, 
    ap.start, ap.end, ap.description
from 
    Table as AP
group by 
    ap.start, ap.end, ap.description

但是当我更改为从有序表中提取此信息时:

Select 
    ot.starttime as "Start Time", 
    ot.endtime as "End Time", 
    ot.description "Description", 
    ot.entrynumber as "ID Number",
    cast((CASE 
             WHEN ot.endtime LIKE '%[^0-9]%' 
                THEN CAST(ot.endtime as datetime) 
             ELSE NULL 
          END)
          -
          (CASE 
              WHEN ot.starttime LIKE '%[^0-9]%' 
                 THEN CAST(ot.starttime as datetime) 
              ELSE NULL 
           END) as time) as duration
From
    OrderedTable as OT
group by
    ot.starttime, ot.endtime, ot.description, ot.entrynumber
order by 
    ot.endtime

我得到了错误。以前应用 group by 子句已删除错误,但未从有序表中删除。

由于我一直在尝试不断消除转换为日期的问题,我不确定是什么导致了问题,我将不胜感激。

最初的问题是服务器上的日期字段是 nvarchar 格式而不是日期时间,我一直在尝试解决这个问题。

【问题讨论】:

  • 大小写表达式,而不是大小写陈述。
  • 很明显,OrderedTable 有不同日期格式的行无法转换。
  • 但是源数据是一样的,ap.starttime = ot.starttime.

标签: sql sql-server-2008 date casting


【解决方案1】:

如果我正确理解您的问题 - 您可以使用

TIMEDIFF(date1, date2)TIMESTAMPDIFF(SECOND, date2, date1);

其中 date2

【讨论】:

  • 我试图直接减去它们
  • case 表达式的原因是它试图删除不是日期格式的错误数据,因为该列是 nvchar 格式而不是日期/时间。问题是,当它应用于正确的表而不是在查询中创建的有序表时,或者放在 OT 子句中时,它可以工作。我只是想弄清问题的根源,因为我正在处理 90+ 千行,我无法轻易看出是什么导致了问题。
  • 我明白了。你能告诉我为什么你检查 starttime 两次(在每种情况下)?因为这里CASE WHEN ot.starttime LIKE '%[^0-9]%' THEN CAST(ot.endtime as datetime) ELSE NULL END你检查开始时间然后转换结束时间
  • 你能提供一些你想减去的2列的示例数据吗?
  • 开始时间两次问题是我的错字(抱歉)。我不确定我是否可以提供我正在使用的数据,尽管它是时间戳格式 (DD/MM/YYY HH:MM:SS),因为我的雇主可能对这种事情非常偏执,如果它是一两个导致问题的条目需要筛选 90,000 行才能完成,目前它位于一个更大的查询中,该查询没有返回具有相同错误的行。我确实按照您的建议尝试了 TIMEDIFF 函数,并取得了一些初步成功,但现在我遇到了同样的问题。
【解决方案2】:

由于该列的格式设置为 nvarchar32 而不是应有的日期/时间,因此导致数据库定期接收结束时间的(某些)打开记录的文本值,而不是 NULL 值。 这只是周期性地发生,无论出于何种原因,设计数据库的人都提出了建议。

这在理想情况下不应该发生,因为它违反了数据库惯例来做这种事情,因为 NULL 值会被计算函数简单地忽略,因为它们是未知的。仍然不清楚为什么 case 表达式没有解决问题,但使用过滤器 FinishTime “错误文本”,我解决了问题。

【讨论】:

    猜你喜欢
    • 2016-12-31
    • 1970-01-01
    • 2014-02-18
    • 2019-12-24
    • 2016-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多