解析具有不同格式的时间字符串并进行比较

时间:2016-02-22 22:48:27

标签: sql postgresql

我正在几个表之间运行查询,我遇到了在不同表上比较两个时间列之间的问题:“rc1_time”是字符串格式,“osemplog_time”是时间格式。两者都是时间,没有日期

rc1_time的内容看起来像'10560684',对应HH24MISSMS

osemplog_time的内容看起来像07:57:02.917455

  1. 如何将rc1_time格式化为没有日期的“时间格式”?
  2. 比较这两次有哪些选择?
  3. 我很欢迎你在这个博览会上回答你的答案

    下面是我的查询

    SELECT
    "public".payroll_master.prm1_name,
    "public".payroll_master.prm1_oe_init,
    "public".receipt.rc1_init,
    "public".employee_log.osemplog_ipaddress,
    "public".employee_log.osemplog_event,
    "public".receipt.rc1_date,
    "public".employee_log.osemplog_logdate,
    "public".receipt.rc1_code,
    "public".employee_log.osemplog_logname,
    "public".oslogname.lognm_empname,
    "public".receipt.rc1_arname,
    "public".receipt.rc1_arnum,
    "public".receipt.rc1_time,
    "public".employee_log.osemplog_logtime
    FROM
    "public".receipt
    INNER JOIN "public".employee_log ON "public".receipt.rc1_date = "public".employee_log.osemplog_logdate
    INNER JOIN "public".payroll_master ON "public".payroll_master.prm1_oe_init = "public".receipt.rc1_init
    INNER JOIN "public".oslogname ON "public".oslogname.lognm_empname = "public".payroll_master.prm1_name AND "public".oslogname.lognm_name = "public".employee_log.osemplog_logname
    WHERE
    "public".receipt.rc1_code = 'CA'
    AND
    "public".employee_log.osemplog_logdate = "public".receipt.rc1_date
    
    ORDER BY
    "public".receipt.rc1_init ASC
    

1 个答案:

答案 0 :(得分:1)

陈述的问题

您可以使用time data type表示没有约会的时间。要将字符串从给定格式转换为一个字符串,您可以浏览to_timestamp函数,然后转换为time

SELECT to_timestamp('10560684', 'HH24MISSUS')::time;
SELECT to_timestamp('07:57:02.917455', 'HH24:MI:SS.US')::time;

基本思想是使用to_timestamp解析时间字符串。生成的timestamp将具有默认日期,并且转换为time将删除日期,只留下已解析的时间部分。

假设:

  • 您的营业时间为24小时制(下午1点至晚上11点为13-23,午夜为00点)。如果它们不是24小时,那么你就错过了AM / PM指定,需要对其进行排序。
  • 你在第一个模式中提到的第二个“SS”实际上是秒的一小部分。如果没有,您需要调整模式。如果您不关心小数秒,您可能会考虑完全关闭US.US并仅在秒级别工作。请注意,US84解释为0.84秒,实际上不是84微秒(0.000084秒)。

最终,您需要提供有关格式的更精确的详细信息,或者自己确定正确的格式字符串。我没有担心这些细节,而是试图举例说明一般机制并将其留给你。

比较是微不足道的。您只需使用PostgreSQL的运算符(<>=等):

SELECT to_timestamp('07:57:02.917455', 'HH24:MI:SS.US')::time < to_timestamp('10560684', 'HH24MISSUS')::time;

其他考虑因素

  • 如果您正在使用时区,请注意时区问题。如果您需要处理时区,则需要查看timetz(简称time with time zone)或timestamptz(简称timestamp with time zone)。一般来说,我建议事先包括时区处理,以防以后出现问题。

  • 在这种情况下,为什么不建立一个完整的timestamp?您已拥有日期:"public".receipt.rc1_date"public".employee_log.osemplog_logdate

    您没有指定数据类型,但无论其形式如何,都应该可以。例如,如果它们是实际的date个对象,那么:

    SELECT to_timestamp(to_char("public".receipt.rc1_date, 'YYYY-MM-DD')||' '||"public".receipt.rc1_time, 'YYYY-MM-DD HH24MISSMS');
    

    如果它们是'YYYY-MM-DD'形式的字符串,那么:

    SELECT to_timestamp("public".receipt.rc1_date||' '||"public".receipt.rc1_time, 'YYYY-MM-DD HH24MISSMS');
    

    等等。现在你有了一个真正的 timestamp,它比简单的更好/更少,更容易。

  • 根据我的经验,您实际上想要以小数秒精度测试时间戳是非常罕见的。您可能需要更宽容的等式检查,例如SELECT t1 - t2 < interval '5 seconds',但这完全取决于应用程序。