我有一张乡村时期表。在某些情况下,某些国家属性(例如资本)在一段时间内的日期发生变化。在这里,我想将国家时期分为两个新时期,一个在此之前,一个在此之后。
示例:
Country | start_date | end_date | event_date
A | 1960-01-01 | 1999-12-31 | 1994-07-20
B | 1926-01-01 | 1995-12-31 | NULL
期望的输出:
Country | start_date | end_date | event_date
A | 1960-01-01 | 1994-07-19 | 1994-07-20
A | 1994-07-20 | 1999-12-31 | 1994-07-20
B | 1926-01-01 | 1995-12-31 | NULL
我考虑从这些行开始 generate_series :
SELECT country, min(p1) as sdate1, max(p1) as sdate2,
min(p2) as sdate2, min(p2) as edate2
FROM
(SELECT country,
generate_series(start_date, (event_date-interval '1 day'), interval '1 day')::date as p1,
generate_series(event_date, end_date, interval '1 day')::date as p2
FROM table)t
GROUP BY country
但这些似乎是低效率和混乱的方式。不幸的是,在编写函数方面我没有任何经验。关于如何解决这个问题的任何想法?
答案 0 :(得分:1)
您可以改为UNION
。这样就不会生成不必要的行
SELECT country, start_date,
CASE WHEN event_date BETWEEN start_date AND end_date
THEN event_date - 1
ELSE end_date
END AS end_date, event_date
FROM table1
UNION ALL
SELECT country, event_date, end_date, event_date
FROM table1
WHERE event_date BETWEEN start_date AND end_date
ORDER BY country, start_date, end_date, event_date
这是SQLFiddle演示
输出:
| country | start_date | end_date | event_date | |---------|------------|------------|------------| | A | 1960-01-01 | 1994-07-19 | 1994-07-20 | | A | 1994-07-20 | 1999-12-31 | 1994-07-20 | | B | 1926-01-01 | 1995-12-31 | (null) |