【问题标题】:How to select rows until the sum of a column reaches N, where the column is of type TIME如何选择行直到列的总和达到 N,其中列的类型为 TIME
【发布时间】:2020-03-28 04:24:23
【问题描述】:

我想选择足够多的音频通话来获得 00:10:00 分钟的音频。我试图通过编写以下 SQL (postgres) 语句来实现这一点

SELECT file_name, audio_duration
FROM (
    SELECT distinct file_name, audio_duration, SUM(audio_duration)
    OVER (ORDER BY audio_duration) AS total_duration
    FROM data
) AS t
WHERE
t.total_duration <='00:10:00'
GROUP BY file_name, audio_duration

我的问题是它似乎没有正确计算总持续时间。 我怀疑这是因为 audio_duration 列是 TIME 类型。

如果有人对如何进行此查询有任何提示或建议,将不胜感激。

【问题讨论】:

  • 请提供样本数据。 audio_duration的数据类型是什么?
  • 什么是duration 类型的time 而不是intervaltime 存储“时刻”,而不是持续时间。
  • 他写道,'audio_duration' 属于 TIME 类型
  • 持续时间的类型是时间类型而不是间隔类型。
  • 我明白,但这是错误的数据类型。要存储持续时间,您应该使用 interval - 您无法及时总结时间点(“早上 8 点”和“下午 3 点”的总和是多少?)

标签: sql postgresql datetime time sum


【解决方案1】:

您确实应该将该列定义为intervaltime 列存储一个时刻,例如“下午三点”。

但是,您可以将单个 time 值强制转换为 interval。如果您想要每个文件的总持续时间,您也不需要窗口函数首先计算“运行总计”:

SELECT file_name, sum(audio_duration::interval) as total_duration
FROM data
GROUP BY file_name
HAVING sum(audio_duration::interval) <= interval '10 minute';

要将列类型永久更改为您可以使用的间隔:

alter table data
  alter duration type interval;

【讨论】:

  • 将尝试转换为区间并尝试您提出的解决方案
【解决方案2】:

我完全同意@a_horse_with_no_name 的观点,即 Interval 是更好的数据类型,但必须承认 Time 数据类型并不正确。虽然您不能添加 (+) 时间数据类型,但您可以对它们求和。对时间数据类型求和会产生一个区间,并产生与对相应区间求和相同的结果。时间除了是时刻之外,也是从一天开始到那一刻的间隔。 Demo (fiddle)

with as_time (dur) as ( values ('10:34:45 AM'::time),  ('03:14:50 PM'::time), ('11:15:25 PM'::time))
   , as_intv (dur) as ( values ('10:34:45'::interval), ('15:14:50'::interval),('23:15:25'::interval))
select *
  from (select sum(dur) sum_time from as_time) st
     , (select sum(dur) sum_intv from as_intv) si; 

顺便说一句:“早上 8 点”和“下午 3 点”之和是多少?嗯,现在是 23:00:00。

【讨论】:

    猜你喜欢
    • 2020-05-31
    • 1970-01-01
    • 2023-02-09
    • 2019-07-02
    • 2019-03-16
    • 2020-08-01
    • 2017-09-22
    • 1970-01-01
    • 2023-01-19
    相关资源
    最近更新 更多