Postgres/Redshift DATEDIFF 转换为 FLOAT

Posted

技术标签:

【中文标题】Postgres/Redshift DATEDIFF 转换为 FLOAT【英文标题】:Postgres/Redshift DATEDIFF convert to FLOAT 【发布时间】:2017-12-14 00:50:51 【问题描述】:

我正在使用 Python SQLAlchemy 连接到 Redshift 实例。我正在尝试在 2 个日期时间之间以分钟计算 DATEDIFF,这很有效。但是当我尝试将结果转换为 FLOAT 并在针对 '

SELECT distinct u2.id,
  CASE 
    WHEN 
      CAST(DATEDIFF(minute, u1.usa_start_datetime::timestamp,u1.usa_end_datetime::timestamp) * 1.00 as FLOAT) < 1.00 
      THEN 1.00 END as fsess_hr,

【问题讨论】:

您期待什么结果?没有ELSE 子句,所以你只会得到1.0NULL 【参考方案1】:

您的CASE 语句中缺少ELSE 子句。如果你想得到1.0,如果差值小于1,否则差值为浮点数,修改你的查询如下:

SELECT distinct 
       u2.id,
       CASE 
         WHEN CAST(DATEDIFF(minute, u1.usa_start_datetime::timestamp,u1.usa_end_datetime::timestamp) * 1.00 as FLOAT) < 1.00 THEN 1.00 
         ELSE CAST(DATEDIFF(minute, u1.usa_start_datetime::timestamp,u1.usa_end_datetime::timestamp) * 1.00 as FLOAT) 
       END as fsess_hr
  FROM some_table

另外,我认为您不需要* 1.00

【讨论】:

【参考方案2】:

DATEDIFF() 的返回类型是BIGINT,您选择使用分钟作为单位。所以处理case expression 中的整数,然后将值转换为浮点数

SELECT /* DISTINCT */ -- is this really needed? 
      u2.id
    , CAST(
            CASE WHEN DATEDIFF(MINUTE, u1.usa_start_datetime ::timestamp, u1.usa_end_datetime ::timestamp)  < 1 THEN 1
                 ELSE DATEDIFF(MINUTE, u1.usa_start_datetime ::timestamp, u1.usa_end_datetime ::timestamp)
            END 
      AS Float) AS fsess_hr
FROM ...

但是你仍然返回了几分钟,所以我不明白为什么它被称为 fsess_hr,你会在某个时候将它除以 60.0 吗?

【讨论】:

【参考方案3】:

我发现 ::float 与 datediff 配合得很好。看起来比cast() as float干净

SELECT distinct u2.id,
CASE 
    WHEN DATEDIFF(minute,u1.usa_start_datetime::timestamp,u1.usa_end_datetime::timestamp)::float < 1.00 
THEN 1.00 END as fsess_hr,

【讨论】:

以上是关于Postgres/Redshift DATEDIFF 转换为 FLOAT的主要内容,如果未能解决你的问题,请参考以下文章

在 Postgres (Redshift) 中使用两个选择列运行 MAX 聚合查询时出现问题

Postgres / Redshift:在一次调用中从组的日期列中提取季度和年份?

在 Redshift 的 JOIN 中使用模式名称

Excel-计算年龄工龄 datedif()

使用datedif函数计算年龄

使用DATEDIF函数计算员工工龄