I have a database table that contains the following data:
ID | Date | Bla
1 | 2013-05-01 | 1
2 | 2013-05-02 | 2
3 | 2013-05-03 | 3
4 | 2013-05-05 | 4
Note that there is a date missing: 2014-05-04
. How should I alter the following query:
SELECT *
FROM table
where DATE >= '2013-05-01' AND DATE <= '2013-05-05'
So that I would end up with the following output:
ID | Date | Bla
1 | 2013-05-01 | 1
2 | 2013-05-02 | 2
3 | 2013-05-03 | 3
null | 2013-05-04 | null
4 | 2013-05-05 | 4
Is this possible?
Wolph
You can join with a generate_series
output:
select
'2013-05-01'::date + g.o AS "date with offset"
from
generate_series(0, 30) AS g(o)
Output:
"2013-05-01"
"2013-05-02"
"2013-05-03"
...
"2013-05-29"
"2013-05-30"
"2013-05-31"
Or... an easier method after defining a new stored procedure :)
CREATE OR REPLACE FUNCTION generate_series(date, date) RETURNS
SETOF date AS $$
SELECT $1 + g.s
FROM generate_series(0, ($2 - $1)) AS g(s);
$$ LANGUAGE SQL IMMUTABLE;
Just call it like this:
SELECT * FROM generate_series(start_date, end_date);
select *
from
(
select generate_series(
'2013-05-01'::date, '2013-05-05', '1 day'
)::date
) s("date")
left join
t using ("date")
Replace both "date"
with the actual column name.
You need to outer join your table against a "list of dates":
with all_dates (some_date) as (
select date '2013-05-01' + i
from generate_series(0, 10) i -- adjust here to the range of dates you need.
)
select t.id,
ad.some_date, -- you need to take the actual date from generated ones
t.bla
from all_dates ad
left join the_table t on ad.some_date = t.date
where ad.some_date between date '2013-05-01' and date '2013-05-05';
Btw: date
is a horrible name for a column. Apart from the fact that it is a reserved word it also tells nothing about what kind of "date" that is.
来源:https://stackoverflow.com/questions/17471385/postgresql-incremental-dates