Thread: date range to set of dates expansion
Hi, How can I expand a date range in a table to a set of date records? I have a table of availabilities thus: Column | Type | Modifiers -----------+-----------------------------+------------------------------------------------------------aid | integer | not null default nextval('availability_aid_seq'::regclass)asid | integer | not nullasdate | date | not nullafdate | date | not nulladays | integer |acomments| text | asdate is the start date afdate is the finish date How can I expand this to a set of Column | Type | Modifiers -----------+-----------------------------+------------------------------------------------------------aid | integer | not null asid | integer | not nulladate | date | not nullacomments | text | i.e. aid | asid | asdate | afdate | adays | acomments -----+------+------------+------------+-------+-------------------- 12 | 1 | 2007-08-11 | 2007-08-12 | 1 | Early finishSunday Becomes aid | asid | asdate | acomments -----+------+------------+-------------------- 12 | 1 | 2007-08-11 | Early finish Sunday 12 | 1 | 2007-08-12 | Earlyfinish Sunday I have a function date_range to return a set of dates, but so far I can't get a valid view to work. Also, is there a better method? CREATE FUNCTION date_range(fdate date, tdate date) RETURNS SETOF date AS $$ DECLARE wdate date; BEGIN return next fdate; wdate:=fdate+1; while wdate <= tdate LOOP return next wdate; wdate:=wdate+1; end LOOP; return; END; $$ LANGUAGE plpgsql; -- Gary Stainburn Group I.T. Manager Ringways Garages http://www.ringways.co.uk
Gary Stainburn <gary.stainburn@ringways.co.uk> writes: > Hi, > > How can I expand a date range in a table to a set of date records? > > I have a table of availabilities thus: > > Column | Type | Modifiers > -----------+-----------------------------+------------------------------------------------------------ > aid | integer | not null default > nextval('availability_aid_seq'::regclass) > asid | integer | not null > asdate | date | not null > afdate | date | not null > adays | integer | > acomments | text | > > > asdate is the start date > afdate is the finish date > > How can I expand this to a set of > > Column | Type | Modifiers > -----------+-----------------------------+------------------------------------------------------------ > aid | integer | not null > asid | integer | not null > adate | date | not null > acomments | text | > > i.e. > > aid | asid | asdate | afdate | adays | acomments > -----+------+------------+------------+-------+-------------------- > 12 | 1 | 2007-08-11 | 2007-08-12 | 1 | Early finish Sunday > > Becomes > > aid | asid | asdate | acomments > -----+------+------------+-------------------- > 12 | 1 | 2007-08-11 | Early finish Sunday > 12 | 1 | 2007-08-12 | Early finish Sunday > > I have a function date_range to return a set of dates, but so far I can't get > a valid view to work. Why don't you just use the built-in PostgreSQL function for that? SELECT aid, asid, generate_series (asdate, afdate, INTERVAL '1 day')::date AS asdate, acomments FROM tbl
On Thursday 19 January 2012 08:32:27 hari.fuchs@gmail.com wrote: > > Why don't you just use the built-in PostgreSQL function for that? > > SELECT aid, asid, > generate_series (asdate, afdate, INTERVAL '1 day')::date AS asdate, > acomments > FROM tbl 1) because I didn't know about it 2) because the version of postgresql I run doesn't support it. However, it does exactly what I need so thanks very much. I'll be upgrading my live server as soon as possible, but in the meantime can anyone suggest a way I can do the same thing using Postgresql 8.1 until I can evaluate 8.4 on my live systems? -- Gary Stainburn Group I.T. Manager Ringways Garages http://www.ringways.co.uk
On Thursday 19 January 2012 15:11:46 Gary Stainburn wrote: > I'll be upgrading my live server as soon as possible, but in the meantime > can anyone suggest a way I can do the same thing using Postgresql 8.1 > until I can evaluate 8.4 on my live systems? Sorry, I meant 8.3 as my current version -- Gary Stainburn Group I.T. Manager Ringways Garages http://www.ringways.co.uk
The following code works in 8.4 but not 8.3. Anyone know why, or what I need to do to change it? SELECT aid, asid, date_range (asdate, afdate)::date AS asdate, acomments FROM availability In 8.4 it returns the expanded dataset as required. In 8.3 I get: ERROR: set-valued function called in context that cannot accept a set CONTEXT: PL/pgSQL function "date_range" line 4 at RETURN NEXT Is there a way to use the integer only generate_series in 8.3 to generate dates by typecasting to/from integers? -- Gary Stainburn Group I.T. Manager Ringways Garages http://www.ringways.co.uk
Sorry for using the list as a scratch-pad for my brain. select aid, asid, generate_series(asdate-'1970-01-01'::date, afdate-'1970-01-01'::date)+'1970-01-01'::date as adate, acomments from availability; Has done the trick. -- Gary Stainburn Group I.T. Manager Ringways Garages http://www.ringways.co.uk
On Thursday, January 19, 2012 7:59:27 am Gary Stainburn wrote: > The following code works in 8.4 but not 8.3. > Anyone know why, or what I need to do to change it? > > SELECT aid, asid, > date_range (asdate, afdate)::date AS asdate, > acomments > FROM availability > > In 8.4 it returns the expanded dataset as required. In 8.3 I get: > > ERROR: set-valued function called in context that cannot accept a set > CONTEXT: PL/pgSQL function "date_range" line 4 at RETURN NEXT As to why it works in 8.4 vs 8.3 http://www.postgresql.org/docs/8.4/interactive/release-8-4.html "Support set-returning functions in SELECT result lists even for functions that return their result via a tuplestore (Tom) In particular, this means that functions written in PL/pgSQL and other PL languages can now be called this way.' In 8.3- I believe you could only call it as SELECT * from date_range (asdate, afdate)::date AS asdate; > > Is there a way to use the integer only generate_series in 8.3 to generate > dates by typecasting to/from integers? -- Adrian Klaver adrian.klaver@gmail.com
On 01/19/2012 07:16 AM, Gary Stainburn wrote: > On Thursday 19 January 2012 15:11:46 Gary Stainburn wrote: >> I'll be upgrading my live server as soon as possible, but in the meantime >> can anyone suggest a way I can do the same thing using Postgresql 8.1 >> until I can evaluate 8.4 on my live systems? I'm sure most here would recommend moving to 9.1 rather than 8.4. Better performance, cooler replication functionality, more advanced in-place upgrade capabilities for future upgrades, a couple years longer before end-of-life, advances to windowing functions and other SQL commands and much other goodness. Cheers, Steve
On Thu, Jan 19, 2012 at 8:20 AM, Adrian Klaver <adrian.klaver@gmail.com> wrote:
On Thursday, January 19, 2012 7:59:27 am Gary Stainburn wrote:As to why it works in 8.4 vs 8.3
> The following code works in 8.4 but not 8.3.
> Anyone know why, or what I need to do to change it?
>
> SELECT aid, asid,
> date_range (asdate, afdate)::date AS asdate,
> acomments
> FROM availability
>
> In 8.4 it returns the expanded dataset as required. In 8.3 I get:
>
> ERROR: set-valued function called in context that cannot accept a set
> CONTEXT: PL/pgSQL function "date_range" line 4 at RETURN NEXT
http://www.postgresql.org/docs/8.4/interactive/release-8-4.html
"Support set-returning functions in SELECT result lists even for functions that
return their result via a tuplestore (Tom)
In particular, this means that functions written in PL/pgSQL and other PL
languages can now be called this way.'
In 8.3- I believe you could only call it as
SELECT * from date_range (asdate, afdate)::date AS asdate;
I don't think you can have that cast there when it is in the from-clause. You can refer to its values in the select clause explicitly if you alias the the results:
select r.range_date::date from date_range(asfdate, afdate) as r(range_date); Presumably, you can fashion something that satisfies your needs by putting something like this in a subquery which refers to the start and end date in each row of the outer query. I'm in a rush, so no time to figure out a working demo for you.
--sam
On 01/19/2012 09:17 AM, Samuel Gendler wrote: > > > On Thu, Jan 19, 2012 at 8:20 AM, Adrian Klaver <adrian.klaver@gmail.com > <mailto:adrian.klaver@gmail.com>> wrote: > > On Thursday, January 19, 2012 7:59:27 am Gary Stainburn wrote: > > The following code works in 8.4 but not 8.3. > > Anyone know why, or what I need to do to change it? > > > > SELECT aid, asid, > > date_range (asdate, afdate)::date AS asdate, > > acomments > > FROM availability > > > > In 8.4 it returns the expanded dataset as required. In 8.3 I get: > > > > ERROR: set-valued function called in context that cannot accept > a set > > CONTEXT: PL/pgSQL function "date_range" line 4 at RETURN NEXT > > As to why it works in 8.4 vs 8.3 > > http://www.postgresql.org/docs/8.4/interactive/release-8-4.html > > "Support set-returning functions in SELECT result lists even for > functions that > return their result via a tuplestore (Tom) > > In particular, this means that functions written in PL/pgSQL and > other PL > languages can now be called this way.' > > In 8.3- I believe you could only call it as > > SELECT * from date_range (asdate, afdate)::date AS asdate; > > > I don't think you can have that cast there when it is in the > from-clause. That was a cut and paste error on my part, I just copied that line from the original query. > -- Adrian Klaver adrian.klaver@gmail.com
On Thursday 19 January 2012 16:50:53 Steve Crawford wrote: > I'm sure most here would recommend moving to 9.1 rather than 8.4. Better > performance, cooler replication functionality, more advanced in-place > upgrade capabilities for future upgrades, a couple years longer before > end-of-life, advances to windowing functions and other SQL commands and > much other goodness. > > Cheers, > Steve Thanks for this Steve. I would have had a look at whatever the latest version is before proceeding. However, I'm running this on an old Fedora 9 box and like to stick to using RPM's. Can I upgrade to 9.1 on a FC9 system using RPM's? Also, the last time I did a server upgrade (FC4 to the FC9 system) upgrading apache, PHP and postgresql broke so many things in my applications it was painful. Can anyone suggest ways I can soak test my systems before upgrading the live system? -- Gary Stainburn Group I.T. Manager Ringways Garages http://www.ringways.co.uk