Use a VALUES
expression to provide multiple rows of input dates.
Then ...
For all versions of Postgres
SELECT cal(a, b)
FROM (
VALUES
('2014-08-02 05:29'::timestamp, '2014-08-02 05:32'::timestamp)
, ('2014-08-02 05:35', '2014-08-02 05:39')
, ('2014-08-02 05:45', '2014-08-02 05:39')
) v(a, b);
You can replace the VALUES
expression with an actual table.
This returns whole rows as a single column (instead of individual columns). You could decompose in place with (cal(a, b)).*
. While this works, it is inefficient. Due to a weakness in the Postgres parser, this would result in multiple evaluation of the function. Detailed explanation:
Instead, use a subquery for better performance:
SELECT (rec).*
FROM (
SELECT cal(a, b)
FROM (
VALUES
('2014-08-02 05:29'::timestamp, '2014-08-02 05:32'::timestamp)
, ('2014-08-02 05:35', '2014-08-02 05:39')
, ('2014-08-02 05:45', '2014-08-02 05:39')
) v(a, b)
) sub;
SQL Fiddle (for pg 8.3 to demonstrate it works in old versions).
Since set-returning functions in the SELECT list are frowned upon by some, and are non-standard SQL.
Postgres 9.3+
That's the main reason why Postgres 9.3 introduced (SQL-standard compliant) LATERAL JOIN
:
SELECT f.*
FROM (
VALUES
('2014-08-02 05:29'::timestamp, '2014-08-02 05:32'::timestamp)
, ('2014-08-02 05:35', '2014-08-02 05:39')
, ('2014-08-02 05:45', '2014-08-02 05:39')
) v(a,b)
, cal(v.a, v.b) f;
The LATERAL JOIN
is implicit here, since the second item in the FROM list references the previous table explicitly. Details:
SQL Fiddle for current Postgres 9.3.