Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate a virtual table to generate a sequence of dates in PostgreSQL?

I'd like to generate a list of dates with the hopes of joining with another table, but I don't know what syntax to use, something similar to this:

SELECT dates.date, transactions.account_id, transactions.amount
  FROM (...) as dates
       LEFT JOIN transactions ON transactions.date = dates.date
 WHERE dates.date >= '2010-01-01' AND dates.date <= '2010-12-31'
 ORDER BY dates.date;

I want the dates so I don't have to further massage the data client-side. I'm using this to display a table similar to this:

Account    2010-01-01    2010-01-02    2010-01-03    Balance
============================================================
Chase 123        +100           -20           -70        +10
Chase 231                       +13            -9         +4
like image 368
François Beausoleil Avatar asked Oct 23 '10 01:10

François Beausoleil


People also ask

What is generate series in PostgreSQL?

Generate a series of numbers in postgres by using the generate_series function. The function requires either 2 or 3 inputs. The first input, [start], is the starting point for generating your series. [ stop] is the value that the series will stop at. The series will stop once the values pass the [stop] value.

What is virtual table in Postgres?

In PostgreSQL, a view is a virtual table based on an SQL statement. It is an abstraction layer, which allows to access the result of a more complex SQL fast an easily. The fields in a view are fields from one or more real tables in the database.

How do I select data between two dates in PostgreSQL?

Use the PostgreSQL AGE() function to retrieve the interval between two timestamps or dates. This function takes two arguments: the first is the end date and the second is the start date.


1 Answers

List of Dates

Use the generate_series function to get a list of numbers that you can add to a date in order to get a list of dates:

SELECT CURRENT_DATE + s.a AS dates 
  FROM generate_series(0,14,7) as s(a);

Result:

dates
------------
2004-02-05
2004-02-12
2004-02-19

Pivoting

The latter part of your question deals with pivoting the result set -- converting row data into columnar data. PIVOT and UNPIVOT are ANSI, but I don't see them as supported by PostgreSQL currently. The most consistently supported means of pivoting a query is to use aggregate functions:

   SELECT t.account,
          SUM(CASE WHEN t.date = '2010-01-01' THEN t.amount END) AS '2010-01-01',
          SUM(CASE WHEN t.date = '2010-01-02' THEN t.amount END) AS '2010-01-02',
          SUM(CASE WHEN t.date = '2010-01-03' THEN t.amount END) AS '2010-01-03',
          SUM(t.amount) AS Balance
     FROM (SELECT CURRENT_DATE + s.a AS dates 
             FROM generate_series(0,14,7) as s(a)) x
LEFT JOIN TRANSACTIONS y ON y.date = x.date
 GROUP BY t.account

Dynamic Columns

...means dynamic SQL.

like image 98
OMG Ponies Avatar answered Oct 19 '22 19:10

OMG Ponies