使用列与时间的差异时的 case 语句错误

case statement error while using difference of columns with time

我想用 case 语句编写一个 select 查询。要求是以秒为单位获得 col1 和 col2 之间的时间差,case 语句就像,如果差异 < 60 秒,则低,如果差异 > 60,则高端作为范围。

到目前为止我尝试的是:

select id, ((col1-col2)*24*60)*60 as diff_secs from table;

这给了我几秒钟的差异,这是完美的。但是为了合并 case 语句,我尝试了以下但没有用。

select id, case when (((col1-col2)*24*60)*60) < 60 then low
                when (((col1-col2)*24*60)*60) > 60 then high
                then end as range
from tble;

我认为您的代码应该可以工作,但我建议:

(case when col1 < col2 + interval '1' minute then 'low'
      when col1 > col2 + interval '1' minute then 'high'
 end)

除了小的打字错误,我想说你可以改写为:

select 
  id, 
  case when col1 < col2 + interval '1' minute then 'low'
       else 'high' 
  end as range
from tble;

请参阅 db<>fiddle 中的 运行 示例。

使用内联视图可以实现:

 select id,case when diff_secs < 60 then 'low' 
                when diff_secs > 60 then 'high'
           end as Range 
  from 
       (select id, ((col1-col2)*24*60)*60 as diff_secs 
        from table) 
  diff_secs_data

PS:查询不处理等于60,您可能需要根据您的要求进行修改。

编辑:要查找 'high' 和 'low' 记录的计数,使用附加内联视图进行聚合就足够了。 可能有多种方式,但我更喜欢使用内联视图,因为这样可以提供更好的可读性。

select Range,count(*)
 from 
 (select id,case when diff_secs < 60 then 'low' 
                when diff_secs > 60 then 'high'
           end as Range 
  from 
       (select id, ((col1-col2)*24*60)*60 as diff_secs 
        from table) 
  diff_secs_data) range_data
  group by Range;

如果您确实在使用 Teradata(您还标记了 Oracle),您可以使用别名稍微简化一下:

SELECT id, (((col1-col2)*24*60)*60) AS time_diff,
  CASE 
    WHEN time_diff < 60 THEN 'low'
    WHEN time_diff > 60 THEN 'high'
  END AS range
from tble;

您可能还想通过向 case 表达式中的操作数之一添加“=”来说明时差恰好为 60 的情况。