Question

I've this table:

CREATE TABLE "mytable"
(  name text,  count integer );
INSERT INTO mytable VALUES ('john', 4),('mark',2),('albert',3);

and I would like "denormlize" the rows in this way:

SELECT name FROM mytable JOIN generate_series(1,4) tmp(a) ON (a<=count)

so I've a number of rows for each name equals to the count column: I've 4 rows with john, 2 with mark and 3 with albert. But i can't use the generate_series() function if I don't know the highest count (in this case 4). There is a way to do this without knowing the MAX(count) ?

Was it helpful?

Solution

select name, 
       generate_series(1,count)
from mytable;

Set returning functions can be used in the select list and will do a cross join with the row retrieved from the base table.

I think this is an undocumented behaviour that might go away in the future, but I'm not sure about that (I recall some discussion regarding this on the mailing list)

SQLFiddle example

OTHER TIPS

DROP TABLE ztable ;
CREATE TABLE ztable (zname varchar, zvalue INTEGER NOT NULL);

INSERT INTO ztable(zname, zvalue) VALUES( 'one', 1), ( 'two', 2 ), ( 'three', 3) , ( 'four', 4 );

WITH expand AS (
        WITH RECURSIVE zzz AS (
        SELECT 1::integer AS rnk , t0.zname
        FROM ztable t0
        UNION
        SELECT 1+rr.rnk , t1.zname
        FROM ztable t1
        JOIN zzz rr ON rr.rnk < t1.zvalue
        )
        SELECT zzz.zname
        FROM zzz
        )
SELECT x.*
FROM expand x
        ;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top