【问题标题】:Extracting the number of days from a calculated interval从计算的间隔中提取天数
【发布时间】:2014-01-29 19:10:51
【问题描述】:

我正在尝试执行如下查询:

SELECT EXTRACT(DAY FROM INTERVAL to_date - from_date) FROM histories;

在引用的表中,to_date 和 from_date 的类型为 timestamp without time zone。像

这样的常规查询
SELECT to_date - from_date FROM histories;

给我间隔结果,例如“65 天 04:58:09.99”。但是在第一个查询中使用这个表达式会给我一个错误:类型间隔的输入语法无效。我尝试了各种引用,甚至没有运气嵌套查询。这个可以吗?

【问题讨论】:

  • 你的第一个表达没有意义。你想用它来达到什么目的?

标签: postgresql


【解决方案1】:

SELECT EXTRACT(DAY FROM INTERVAL to_date - from_date) FROM histories;

这毫无意义。 INTERVAL xxx 是区间文字的语法。所以INTERVAL from_date 是一个语法错误,因为from_date 不是文字。如果你的代码看起来更像INTERVAL '2012-02-01',那么这将失败,因为2012-02-01 不是INTERVAL 的有效语法。

这里的INTERVAL 关键字只是噪音。我怀疑您误解了文档中的一个示例。去掉它,表达式就可以了。

我猜您正在尝试获取两个日期之间的天数,表示为 timestamptimestamptz

如果是这样,要么将两者都转换为日期:

SELECT to_date::date - from_date::date FROM histories;

或者获取区间,然后提取天分量:

SELECT extract(day from to_date - from_date) FROM histories;

【讨论】:

    【解决方案2】:

    这个例子演示了创建一个带有触发器的表,它更新了 DDD HH24:MI:SS 格式的 stop_time 和 start_time 之间的差异,其中 DDD 代表日期的数量......

    DROP TABLE IF EXISTS benchmarks ;
    
      SELECT 'create the "benchmarks" table'
      ;
         CREATE TABLE benchmarks (
            guid           UUID NOT NULL DEFAULT gen_random_uuid()
          , id             bigint UNIQUE NOT NULL DEFAULT cast (to_char(current_timestamp, 'YYMMDDHH12MISS') as bigint)
          , git_hash                char (8) NULL DEFAULT 'hash...'
          , start_time              timestamp NOT NULL DEFAULT DATE_TRUNC('second', NOW())
          , stop_time               timestamp NOT NULL DEFAULT DATE_TRUNC('second', NOW())
          , diff_time               varchar (20) NOT NULL DEFAULT 'HH:MI:SS'
          , update_time             timestamp DEFAULT DATE_TRUNC('second', NOW())
          , CONSTRAINT pk_benchmarks_guid PRIMARY KEY (guid)
          ) WITH (
            OIDS=FALSE
          );
    
      create unique index idx_uniq_benchmarks_id on benchmarks (id);
    
    -- START trigger trg_benchmarks_upsrt_diff_time
    -- hrt = human readable time
    CREATE OR REPLACE FUNCTION fnc_benchmarks_upsrt_diff_time()
    
        RETURNS TRIGGER
        AS $$
           BEGIN
              -- NEW.diff_time = age(NEW.stop_time::timestamp-NEW.start_time::timestamp);
              NEW.diff_time = to_char(NEW.stop_time-NEW.start_time, 'DDD HH24:MI:SS');
              RETURN NEW;
           END;
        $$ LANGUAGE plpgsql;
    
    
     CREATE TRIGGER trg_benchmarks_upsrt_diff_time
      BEFORE INSERT OR UPDATE ON benchmarks
      FOR EACH ROW EXECUTE PROCEDURE fnc_benchmarks_upsrt_diff_time();
    --
    -- STOP trigger trg_benchmarks_upsrt_diff_time
    

    【讨论】:

      【解决方案3】:

      只需删除关键字 INTERVAL:

      SELECT EXTRACT(DAY FROM to_date - from_date) FROM histories;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-02-04
        • 1970-01-01
        • 2022-11-25
        • 1970-01-01
        • 2012-10-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多