3

I have a postgres function called site_opened_on_date which take as input an id and a date. The function's signature looks like this :

CREATE OR REPLACE FUNCTION recntrek.site_opened_on_date(
site_id bigint,
in_date date DEFAULT (
now(
))::date)
RETURNS SETOF "TABLE(date date, opening_time time without time zone, closing_time time without time zone)"
LANGUAGE 'plpgsql'
COST 5.0
STABLE 
ROWS 3.0
AS $function$

I want to apply this function on 7 days. I have tried this:

SELECT (
SELECT t FROM site_opened_on_date(100520000101526, _d) t
)FROM unnest(ARRAY[ now(),
 now()+ INTERVAL '1 DAY',
 now()+ INTERVAL '2 DAY',
 now()+ INTERVAL '3 DAY',
 now()+ INTERVAL '4 DAY',
 now()+ INTERVAL '5 DAY',
 now()+ INTERVAL '6 DAY'
]::DATE[])  _d;

But I get the following error: more than one row returned by a subquery used as an expression This is due to the fact that the site_opened_on_date function can return more than one row for a date. Anyone has an idea of a solution ? I would rather not write a new postgres function, I would prefer to find a way to apply my array to the existing function in a query.

1
  • it should also be possible to use a function param as array with in_date date[] in postgresql.. and call the function like SELECT site_opened_on_date(100520000101526, ARRAY[ now(), now()+ INTERVAL '1 DAY', now()+ INTERVAL '2 DAY', now()+ INTERVAL '3 DAY', now()+ INTERVAL '4 DAY', now()+ INTERVAL '5 DAY', now()+ INTERVAL '6 DAY' ]::DATE[]) Commented Apr 28, 2018 at 21:34

2 Answers 2

1

You can easily generate a series of consecutive dates with the function generate_series(start, stop, step interval):

SELECT t.*
FROM generate_series(now(), now()+ '6 days', '1 day') as _d
CROSS JOIN LATERAL site_opened_on_date(100520000101526, _d::date) t

or

SELECT (site_opened_on_date(100520000101526, _d::date)).*
FROM generate_series(now(), now()+ '6 days', '1 day') as _d

Use

SELECT t.* 

instead of

SELECT t

to get resulting rows in columns (instead of a single column with tuples).

Sign up to request clarification or add additional context in comments.

Comments

1

You don't need to use subquery. Just do:

SELECT
    (recntrek.site_opened_on_date(100520000101526, _d)).*
FROM
    unnest( ARRAY[
            now(),
            now()+ INTERVAL '1 DAY',
            now()+ INTERVAL '2 DAY',
            now()+ INTERVAL '3 DAY',
            now()+ INTERVAL '4 DAY',
            now()+ INTERVAL '5 DAY',
            now()+ INTERVAL '6 DAY'
        ]::DATE[]) _d;

See example here.

2 Comments

Thank you ! I don't get an error anymore. Is there a way I can receive also the column name (date, opening_time, closing_time) in my result ? I would like to have a chart as a result (with column names). Thanks!
Use SELECT (recntrek.site_opened_on_date(100520000101526, _d)).* FROM ... to get separate columns.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.