2010-09-23 70 views
4

我们有一些表格,其中有这样的结构:如何使用PostgreSQL将开始/结束时间列拆分为离散块?

开始, - 日期时间
末 , - 日期时间
成本 - 十进制

所以,举例来说,有可能是这样的一行:

01/01/2010 10:08,01/01/2010下午1:56,135.00
01/01/2010上午11点01分,01/01/2010下午3:22,118.00
01/01/2010 06:19 pm,01/02/2010 1:43 am,167.00

等...

我想获得这个成格式的格式返回数据,如(带功能?):

上午10:00,上午10:15,X,Y ,Z
上午10:15,上午10:30,X,Y,Z
上午10:30,上午10:45,X,Y,Z
上午10:45,上午11:00,X,Y,Z
11 :00am,11:15 am,X,Y,Z

....

其中:
X =匹配
Y =成本/费用的时间该块的行数
Z =该时间持续时间

IE期间的总量,对于上述数据,我们可能有:

上午10:00,上午10:15,1,(二百二十八分之一百三十五分钟* 7),7

  • 第一行开始于10:08,所以只有7分钟从使用10:00-10:15。
  • 开始 - 结束时间有228分钟。

....

上午11时,上午11点15分,2,((135 + 118)/((228 + 261)*分钟(15 + 14)),29

  • 第二排上午11:00之后开始,所以我们需要从第一行15分钟后,加上从第二排14分钟
  • 有第二开始 - 261分钟>结束时间

....

我相信我已经在这里完成了数学计算,但需要弄清楚如何使它成为一个PG函数,以便它可以在报告中使用。

理想情况下,我希望能够调用一些任意的持续时间,即15分钟,或30分钟,或60分钟的功能,并基于此分解。

任何想法?

回答

5

这是我的尝试。鉴于此表定义:

CREATE TABLE interval_test 
(
    "start" timestamp without time zone, 
    "end" timestamp without time zone, 
    "cost" integer 
) 

此查询似乎做你想做的。不知道它是否是最好的解决方案。 还要注意,它需要Postgres 8.4才能工作,因为它使用WINDOW函数和WITH查询。

WITH RECURSIVE intervals(period_start) AS (
    SELECT 
    date_trunc('hour', MIN(start)) AS period_start 
     FROM interval_test 

    UNION ALL 
    SELECT intervals.period_start + INTERVAL '15 MINUTES' 
     FROM intervals 
     WHERE (intervals.period_start + INTERVAL '15 MINUTES') < (SELECT MAX("end") FROM interval_test) 
) 
    SELECT DISTINCT period_start, intervals.period_start + INTERVAL '15 MINUTES' AS period_end, 
    COUNT(*) OVER (PARTITION BY period_start) AS record_count, 
SUM (LEAST(period_start + INTERVAL '15 MINUTES', "end")::timestamp - GREATEST(period_start, "start")::timestamp) 
    OVER (PARTITION BY period_start) AS total_time, 

    (SUM(cost) OVER (PARTITION BY period_start)/ 


(EXTRACT(EPOCH FROM SUM("end" - "start") OVER (PARTITION BY period_start))/60)) * 

((EXTRACT (EPOCH FROM SUM (LEAST(period_start + INTERVAL '15 MINUTES', "end")::timestamp - GREATEST(period_start, "start")::timestamp) 
    OVER (PARTITION BY period_start)))/60) 

    AS expense 

FROM interval_test 
INNER JOIN intervals ON (intervals.period_start, intervals.period_start + INTERVAL '15 MINUTES') OVERLAPS (interval_test.start, interval_test.end) 

ORDER BY period_start ASC 
+0

这看起来很近!似乎错过了“成本”/费用元素。 – Anthony 2010-09-24 04:09:32

+0

我更新了查询以包含成本/费用。我不确定我得到了计算应该做什么,但是您应该可以根据自己的目的修改查询。 – jira 2010-09-24 11:51:41

相关问题