为什么 postgres 对相同的间隔值显示两种不同的格式?

2023-11-21

我正在帮忙做这件事question尝试更改间隔的格式。

from '01 day 22:10:37'  to  '46:10:37'

我给出了一个字符串操作的解决方案。但后来我发现 postgres 可以在两种不同的格式上显示相同的间隔。

SELECT '2016-01-27 08:51:02'::timestamp - '2016-01-25 10:40:25'::timestamp end_date,
       '46:10:37'::interval interval_date;

有趣的事情。有一个function进行逆过程

 justify_hours('46:10:37'::interval) --> '1 day 22:10:37'

所以我想知道是否有直接的方法来解决这个问题。为什么相同的区间值有两个不同的结果。

pgAdmin 输出:

enter image description here


当一个区间为两个时间戳之间的差异它总是以小时为单位(即它有standard格式)。例子:

select
    '2015-01-01 13:0:0'::timestamp - '2014-01-01 23:0:0'::timestamp, --> 364 days 14:00:00
    '2015-01-01 13:0:0'::timestamp - '2014-01-01 03:0:0'::timestamp, --> 365 days 10:00:00
    '2015-01-01 13:0:0'::timestamp - '2015-01-01 03:0:0'::timestamp; --> 10:00:00

间隔计算分别对日期部分和时间部分执行,因此它们可能会导致奇怪的格式。例子:

select 
    '2 day 1:00:00'::interval- '1 day 2:00:00'::interval,    --> 1 day -01:00:00 (!!)
    '2 day 100:00:00'::interval+ '1 day 60:00:00'::interval, --> 3 days 160:00:00
    '2 day 100:00:00'::interval- '2 day 60:00:00'::interval; --> 40:00:00

对于这种情况,Postgres 开发人员提供了适当的函数格式标准化:

select 
    justify_hours('1 day -01:00:00'),  --> 23:00:00
    justify_hours('3 days 160:00:00'), --> 9 days 16:00:00
    justify_hours('40:00:00');         --> 1 day 16:00:00

然而他们认为没有必要进行相反的操作。在这个答案我提出了一个将间隔的日期部分转换为小时的函数。我认为它可以是(有一些微小的改变)某种反向功能 for justify_hours():

create or replace function unjustify_hours(interval)
returns interval language sql as $$
    select format('%s:%s',
        (extract (epoch from $1) / 3600)::int,
        to_char($1, 'mi:ss'))::interval;
$$;

select 
    unjustify_hours('23:00:00'),        --> 23:00:00
    unjustify_hours('9 days 16:00:00'), --> 232:00:00
    unjustify_hours('1 day 16:00:00');  --> 40:00:00

功能to_char(interval, text)在这里没有帮助,因为

select 
    to_char(interval '23:00:00', 'hh24:mi:ss'),        --> 23:00:00
    to_char(interval '9 days 16:00:00', 'hh24:mi:ss'), --> 16:00:00 (!)
    to_char(interval '1 day 16:00:00',  'hh24:mi:ss'); --> 16:00:00 (!)

请注意,可以通过多种方式正确格式化间隔:

select 
    justify_hours('100:00:00'),        --> 4 days 04:00:00
    justify_hours('1 days 76:00:00'),  --> 4 days 04:00:00
    justify_hours('2 days 52:00:00'),  --> 4 days 04:00:00
    justify_hours('5 days -20:00:00'); --> 4 days 04:00:00

Per 文档:

根据 SQL 标准,区间值的所有字段都必须 具有相同的符号,因此前导负号适用于所有字段; 例如间隔文字 '-1 2:03:04' 中的负号 适用于天和小时/分钟/秒部分。 PostgreSQL 允许田地有不同的标志,并且传统上对待 文本表示中的每个字段都是独立签名的,因此 小时/分钟/秒部分被认为是积极的 例子。如果 IntervalStyle 设置为 sql_standard,则为前导符号 被认为适用于所有领域(但前提是没有附加标志 出现)。否则使用传统的 PostgreSQL 解释。 为避免歧义,建议附加明确的标志 每个字段(如果有任何字段为负)。

and

内部间隔值存储为月、日和秒。 这样做是因为一个月中的天数不同,并且一天 如果夏令时调整为 23 或 25 小时 涉及。月份和日期字段是整数,而秒字段是 字段可以存储分数。因为间隔通常是从创建的 常量字符串或时间戳减法,这种存储方法有效 在大多数情况下都很好。函数 justify_days 和 justify_hours 是 可调整超出正常范围的日期和时间 范围。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 postgres 对相同的间隔值显示两种不同的格式? 的相关文章

  • Postgresql 使用 IN 与 NOT IN 时的巨大性能差异

    我有两张桌子 transaksi 和 buku transaksi 大约有 25 万行 buku 大约有 17 万行 两个表都有名为 k999a 的列 并且两个表均不使用索引 现在我检查这两个陈述 声明一 explain select k9
  • 按两列的最小值排序

    I use SQL Server 2008 R2 我需要按两列的最小值对表进行排序 该表如下所示 ID integer Date1 datetime Date2 datetime 我希望我的数据按至少两个日期排序 以这种方式对该表进行排序的
  • MySQL 中的 group_concat 性能问题

    我添加了一个group concat到一个查询并杀死了性能 添加之前和之后的解释计划是相同的 所以我对如何优化它感到困惑 这是查询的简化版本 SELECT curRow curRow 1 AS row number docID docTyp
  • 如何在SqlAlchemy中执行“左外连接”

    我需要执行这个查询 select field11 field12 from Table 1 t1 left outer join Table 2 t2 ON t2 tbl1 id t1 tbl1 id where t2 tbl2 id is
  • 将一个大的 postgres 表拆分为多个 csv

    我正在使用以下 psql 查询连接到远程主机并将一个大表拆分为多个 csv 文件 psql h xx p xx U xx d xx c COPY select from table TO program split lines 1000 f
  • MySQL:为什么 IN 子句中的第 5 个 ID 会极大地改变查询计划?

    给出以下两个查询 Query 1 SELECT log id FROM log WHERE user id IN 188858 188886 189854 203623 204072 and type in 14 15 17 ORDER B
  • PHP json_encode 反斜杠和数组名称的问题

    我正在将一些 postgresql 数据转换为 PHP json encode 但我遇到了一些问题 json encode 将 BackSlash 添加到我的数据中的所有斜杠中 在描述中出现段落标记的结束 我认为是因为反斜杠问题 我不希望我
  • 如何从函数返回更新的行

    我对 postgres 很陌生 我想创建一个函数 如存储过程 来更新多行并选择受影响的行 这是我的声明 CREATE or replace FUNCTION set val val character varying 100 5 RETUR
  • PLSQL 中的时区转换

    我需要将系统日期和时间转换为特定时区 例如东部时间 我无法假设我当前的时区 如何在plsql中转换它 请帮我 假设你有一个TIMESTAMP WITH TIME ZONE 例如systimestamp 您可以使用AT TIME ZONE句法
  • 执行存储过程时 ExecuteNonQuery() 返回 -1

    我正在尝试在 Visual Studio 中执行存储过程 下面给出 CREATE PROCEDURE dbo addStudent stuName varchar 50 address varchar 100 tel varchar 15
  • 当您执行“SELECT *”时,SQL Server 如何确定列的顺序?

    当您执行以下操作时 SQL Server 如何确定列的顺序SELECT 我知道 订购依据 对于订购至关重要data 但我预计列名保持一致 注意 我的代码是not取决于返回列的实际顺序 我只想知道 SQL Server 如何决定对列名进行排序
  • MySQL创建表中的日期格式

    我必须使用 MySql 创建一个表 它可以按以下格式存储日期 我尝试过如下 CREATE TABLE birth date DATE 但它不起作用 因为日期格式是 YYYY MM DD 我该怎么办 谢谢 MySQL 或几乎任何其他数据库 中
  • SQL Server 2008 中的 FREETEXT 查询不进行短语匹配

    我在 SQL Server 2008 中有一个全文索引表 我正在尝试使用 FULLTEXT 查询精确的短语匹配 我不认为使用 CONTAINS 或 LIKE 适合于此 因为在其他情况下查询可能不准确 用户没有用双引号括起短语 并且一般来说我
  • 从 URL 生成报告 - SQL Server Reporting Services 2008

    我有 SQL Server Reporting Services 2008 当我打开以下 URL 时 http localhost Reports Pages Report aspx someReport 我正在进入报告屏幕 在其中填写参数
  • 插入MYSQL时自动初始化GETDATE()

    类似问题 https stackoverflow com questions 17700239 mysql column automaticly current time of insert w3schools 也许有用的链接 http w
  • 如何获取 PostgreSQL 中表上所有索引的列名列表?

    我有这个查询来获取表上的索引列表 SELECT ns nspname as schema name tab relname as table name cls relname as index name am amname as index
  • SQL最近的命令?微软SQL

    我只是编写一个查询来查看我的客户数据库并列出他们下了多少订单等 我正在努力添加到此查询中的是只显示该电子邮件的最新 OrderID 有任何想法吗 这是我的查询 select top 1000 BuyerEMail COUNT HowMany
  • SSRS 报告 - IIF 声明问题

    做一个表达式时出现错误 有人可以在这里告诉我正确的语法吗 IIf Fields t cpcp Value 310 Purchased Material Raw Material Nothing IIf Fields t cpcp Value
  • 如何使用默认约束为mysql中的列创建随机数?

    DEFAULT 约束在接受字符串或当前日期值方面没有问题 我需要的是一个约束 每次创建实体时都会创建一个随机的 4 位数字 我尝试了以下代码 但它返回语法错误 ALTER TABLE client number ADD 代码 INT 4 D
  • 检索前 10 行并对第 11 行中的所有其他行求和

    我有以下查询来检索每个国家 地区的用户数量 SELECT C CountryID AS CountryID C CountryName AS Country Count FirstName AS Origin FROM Users AS U

随机推荐