pg.ddx.io  pgsql-sql@postgresql.org mailing list archive  
help / color / mirror / Atom feed
Expressing a result set as an array (and vice versa)?
6+ messages / 5 participants
[nested] [flat]

* Expressing a result set as an array (and vice versa)?
@ 2006-03-23 19:44  Don Maier <dMaier@genome.stanford.edu>
  0 siblings, 2 replies; 6+ messages in thread

From: Don Maier @ 2006-03-23 19:44 UTC (permalink / raw)
  To: pgsql-sql

Good day,

Is it possible to construct an array from an appropriate select  
expression that generates a result set of unknown cardinality?
To focus on the simple case:  Is it possible to construct a one- 
dimensional array from a select of a single column in a table with an  
unknown number of rows?

Conversely, is it possible to construct a (single column) result set  
from a select expression on a one-dimensional array with an unknown  
number of elements?

Thanks for any hints!

Regards,
Don Maier





^ permalink  raw  reply  [nested|flat] 6+ messages in thread

* Re: Expressing a result set as an array (and vice versa)?
@ 2006-03-24 23:17  PFC <lists@peufeu.com>
  parent: Don Maier <dMaier@genome.stanford.edu>
  1 sibling, 1 reply; 6+ messages in thread

From: PFC @ 2006-03-24 23:17 UTC (permalink / raw)
  To: Don Maier <dMaier@genome.stanford.edu>; pgsql-sql



CREATE OR REPLACE FUNCTION foreach( liste INTEGER[] ) RETURNS SETOF  
INTEGER AS $$
DECLARE
   i INTEGER;
BEGIN
   FOR i IN 1..icount(liste) LOOP
     RETURN NEXT liste[i];
   END LOOP;
END;
$$ LANGUAGE plpgsql;

CREATE AGGREGATE array_accum (
     sfunc = array_append,
     basetype = anyelement,
     stype = anyarray,
     initcond = '{}'
);

SELECT array_accum( DISTINCT list_id ) FROM bookmarks;
   array_accum
---------------
  {1,2,3,4,5,7}

SELECT * FROM foreach( '{1,2,3,4,5,7}' );
  foreach
---------
        1
        2
        3
        4
        5
        7



On Thu, 23 Mar 2006 20:44:32 +0100, Don Maier <dMaier@genome.stanford.edu>  
wrote:

> Good day,
>
> Is it possible to construct an array from an appropriate select  
> expression that generates a result set of unknown cardinality?
> To focus on the simple case:  Is it possible to construct a one- 
> dimensional array from a select of a single column in a table with an  
> unknown number of rows?
>
> Conversely, is it possible to construct a (single column) result set  
> from a select expression on a one-dimensional array with an unknown  
> number of elements?
>
> Thanks for any hints!
>
> Regards,
> Don Maier
>
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 1: if posting/reading through Usenet, please send an appropriate
>        subscribe-nomail command to majordomo@postgresql.org so that your
>        message can get through to the mailing list cleanly





^ permalink  raw  reply  [nested|flat] 6+ messages in thread

* Re: Expressing a result set as an array (and vice versa)?
@ 2006-03-26 03:11  george young <gry@ll.mit.edu>
  parent: Don Maier <dMaier@genome.stanford.edu>
  1 sibling, 1 reply; 6+ messages in thread

From: george young @ 2006-03-26 03:11 UTC (permalink / raw)
  To: pgsql-sql

On Thu, 23 Mar 2006 11:44:32 -0800
Don Maier <dMaier@genome.stanford.edu> threw this fish to the penguins:

> Is it possible to construct an array from an appropriate select  
> expression that generates a result set of unknown cardinality?
> To focus on the simple case:  Is it possible to construct a one- 
> dimensional array from a select of a single column in a table with an  
> unknown number of rows?

   select array(select some_int_field from my_table where something);

produces an array of integers.  No user defined function is required.

> Conversely, is it possible to construct a (single column) result set  
> from a select expression on a one-dimensional array with an unknown  
> number of elements?
Not so easy without a custom function.

> Thanks for any hints!
> 
> Regards,
> Don Maier
> 
> 
> 
> ---------------------------(end of broadcast)---------------------------
> TIP 1: if posting/reading through Usenet, please send an appropriate
>        subscribe-nomail command to majordomo@postgresql.org so that your
>        message can get through to the mailing list cleanly
> 


-- 
"Are the gods not just?"  "Oh no, child.
What would become of us if they were?" (CSL)



^ permalink  raw  reply  [nested|flat] 6+ messages in thread

* Re: Expressing a result set as an array (and vice versa)?
@ 2006-03-26 05:56  Volkan YAZICI <yazicivo@ttnet.net.tr>
  parent: george young <gry@ll.mit.edu>
  0 siblings, 0 replies; 6+ messages in thread

From: Volkan YAZICI @ 2006-03-26 05:56 UTC (permalink / raw)
  To: george young <gry@ll.mit.edu>; +Cc: pgsql-sql

On Mar 25 10:11, george young wrote:
> On Mar 23 11:44, Don Maier <dMaier@genome.stanford.edu> wrote:
> > Conversely, is it possible to construct a (single column) result set  
> > from a select expression on a one-dimensional array with an unknown  
> > number of elements?
>
> Not so easy without a custom function.

But not that hard:

test=> SELECT id, val FROM t_arr;
 id |      val      
----+---------------
  1 | {1,2,3}
  2 | {4,5,6}
  3 | {7,8,9}
  4 | {10,11,12,13}
(4 rows)

--
-- First Way
--
test=> SELECT id, val[s.i]
test-> FROM t_arr
test-> LEFT OUTER JOIN
test->   (SELECT g.s
test(>      FROM generate_series(1, (SELECT max(array_upper(val, 1)) FROM t_arr)) AS g(s)
test(>   ) AS s(i)
test->   ON (s.i <= array_upper(val, 1));
 id | val 
----+-----
  1 |   1
  1 |   2
  1 |   3
  2 |   4
  2 |   5
  2 |   6
  3 |   7
  3 |   8
  3 |   9
  4 |  10
  4 |  11
  4 |  12
  4 |  13
(13 rows)

--
-- Second Way (by using contrib/intagg)
--
SELECT id, int_array_enum(val) FROM t_arr;


Regards.



^ permalink  raw  reply  [nested|flat] 6+ messages in thread

* Re: Expressing a result set as an array (and vice versa)?
@ 2006-03-27 13:48  Jim C. Nasby <jnasby@pervasive.com>
  parent: PFC <lists@peufeu.com>
  0 siblings, 1 reply; 6+ messages in thread

From: Jim C. Nasby @ 2006-03-27 13:48 UTC (permalink / raw)
  To: PFC <lists@peufeu.com>; +Cc: Don Maier <dMaier@genome.stanford.edu>; pgsql-sql

On Sat, Mar 25, 2006 at 12:17:08AM +0100, PFC wrote:
> 
> 
> CREATE OR REPLACE FUNCTION foreach( liste INTEGER[] ) RETURNS SETOF  
> INTEGER AS $$
> DECLARE
>   i INTEGER;
> BEGIN
>   FOR i IN 1..icount(liste) LOOP
>     RETURN NEXT liste[i];
>   END LOOP;
> END;
> $$ LANGUAGE plpgsql;

Seems like this should really exist in the backend...

> CREATE AGGREGATE array_accum (
>     sfunc = array_append,
>     basetype = anyelement,
>     stype = anyarray,
>     initcond = '{}'
> );
> 
> SELECT array_accum( DISTINCT list_id ) FROM bookmarks;
>   array_accum
> ---------------
>  {1,2,3,4,5,7}

Couldn't you just use array()?
-- 
Jim C. Nasby, Sr. Engineering Consultant      jnasby@pervasive.com
Pervasive Software      http://pervasive.com    work: 512-231-6117
vcard: http://jim.nasby.net/pervasive.vcf       cell: 512-569-9461



^ permalink  raw  reply  [nested|flat] 6+ messages in thread

* Re: Expressing a result set as an array (and vice versa)?
@ 2006-03-27 15:12  PFC <lists@peufeu.com>
  parent: Jim C. Nasby <jnasby@pervasive.com>
  0 siblings, 0 replies; 6+ messages in thread

From: PFC @ 2006-03-27 15:12 UTC (permalink / raw)
  To: Jim C. Nasby <jnasby@pervasive.com>; +Cc: pgsql-sql


>> SELECT array_accum( DISTINCT list_id ) FROM bookmarks;
>>   array_accum
>> ---------------
>>  {1,2,3,4,5,7}
>
> Couldn't you just use array()?

	Yes, you can do this :

SELECT ARRAY( SELECT something with one column );

	However, array_accum() as an aggregate is more interesting because you  
can use GROUP BY. For instance :

SELECT parent, array_accum( child ) FROM table GROUP BY parent;


	I have another question. Suppose I have these tables :

CREATE TABLE items (
	id	SERIAL PRIMARY KEY,
	category	INTEGER NOT NULL,
	name	TEXT NOT NULL,
);

CREATE TABLE comments (
	item_id		INTEGER NOT NULL REFERENCES items(id),
	id		SERIAL PRIMARY KEY,
	comment	TEXT NOT NULL,
	added		TIMESTAMP NOT NULL DEFAULT now()
)

	Say I want to display some items and the associated comments :

	SELECT * FROM items WHERE category = ...

	Then, I gather the item ids which were returned by this query, and do :

	SELECT * FROM comments WHERE item_id IN ( the ids ) ORDER BY item_id,  
added;

	Is there a more elegant and efficient way which would avoid making a big  
IN() query ? I could join comments with items, but in my case the search  
condition on items is quite complicated and slow ; hence I only want to do  
the search once. And I have several different tables in the same style of  
the "comments" table, and so I make several queries using the same IN  
(...) term. It isn't very elegant... is there a better way ? Use a  
temporary table ? How do you do it ?



^ permalink  raw  reply  [nested|flat] 6+ messages in thread


end of thread, other threads:[~2006-03-27 15:12 UTC | newest]

Thread overview: 6+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2006-03-23 19:44 Expressing a result set as an array (and vice versa)? Don Maier <dMaier@genome.stanford.edu>
2006-03-24 23:17 ` PFC <lists@peufeu.com>
2006-03-27 13:48   ` Jim C. Nasby <jnasby@pervasive.com>
2006-03-27 15:12     ` PFC <lists@peufeu.com>
2006-03-26 03:11 ` george young <gry@ll.mit.edu>
2006-03-26 05:56   ` Volkan YAZICI <yazicivo@ttnet.net.tr>

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox