在SQL中将单行拆分为多行

时间:2014-03-14 07:44:38

标签: sql postgresql postgresql-9.1

在我的表中有两个字段start和stop,分别存储开始时间和停止时间。

例如,开始时间= 2014-01-01 23:43:00并且停止= 2014-01-03 03:33:00。这个时间戳需要解读。

1=> 2014-01-01 23:43:00 - 2014-01-02 00:00:00, as date 2014-01-01
2=> 2014-01-02 00:00:01 - 2014-01-03 00:00:00, as date 2014-01-02 
3=> 2014-01-03 00:00:01 - 2014-01-03 03:33:00, as date 2014-01-03 

作为三个不同的行。

这里的问题是停止和开始时间的差异在1天到10天之间变化。

为了使其更复杂,在上面的例子中我根据日期分割期间,这需要根据时间分割即。说时间02:30:00分裂,所以吐痰应该如下。

1=> 2014-01-01 23:43:00 - 2014-01-02 02:30:00, as date 2014-01-01 
2=> 2014-01-02 02:30:01 - 2014-01-03 02:30:00, as date 2014-01-02 
3=> 2014-01-03 02:30:01 - 2014-01-03 02:30:00, as date 2014-01-03 
4=> 2014-01-03 02:30:01 - 2014-01-03 03:33:00, as date 2014-01-04 

完成上述拆分后,我需要计算按日期分组的行数。

我正在使用PostgreSQL

任何人都可以对此有所了解!!

谢谢!

3 个答案:

答案 0 :(得分:2)

我认为你的"按时间划分"所需的输出样本是错误的,应该 而不是这个

1=> 2014-01-01 23:43:00 - 2014-01-02 02:30:00, as date 2014-01-01 
2=> 2014-01-02 02:30:01 - 2014-01-03 02:30:00, as date 2014-01-02 
3=> 2014-01-03 02:30:01 - 2014-01-03 03:33:00, as date 2014-01-03 

如果是这种情况那就这样做

select day, count(*)
from (
    select generate_series(
        (start_time - interval '2 hours 30 minutes')::date,
        stop_time,
        interval '1 day'
    )::date as day
    from t
) s
group by day
order by day

答案 1 :(得分:1)

创建一个附属表 - period并在表格中插入所有可能的句点,让我们说from now() -10 years to now()+10 years

如果是几天,则应该是20年的所有日子。

之后,您可以从period表中进行选择,并使用句点提取代码

加入您的表格

答案 2 :(得分:1)

您可能需要一个包含每个日期的附加表,以将其加入基表。

如果您有一个类似dates的表格,其中包含以下值:

date_col
2014-01-01 00:00:00
2014-01-02 00:00:00
2014-01-03 00:00:00
...

然后你可以进行像

这样的查询
SELECT GREATEST(start_time, date_col), LEAST(end_time,date_col + interval 1 day) FROM base_table
JOIN dates ON date_col BETWEEN start_time AND end_time

SQL没有经过测试,但它显示出了想法。