2012-09-25 25 views
3

我有這個表:PostgreSQL的加入到反規範化與generate_series表

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

,我想用這種方式「denormlize」行:

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

所以我有個號每行的行數等於計數列:我有約4行,標記2和阿爾伯特3。 但我不能使用generate_series()函數,如果我不知道最高的計數(在這種情況下4)。有一種方法可以在不知道MAX(計數)的情況下做到這一點?

回答

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

集返回功能可以在select列表中使用,並會做與基表中檢索行交叉聯接。

認爲這是一個無證的行爲可能消失在未來,但我不知道這一點(我記得在郵件列表中對此進行一些討論)

SQLFiddle example

+0

非常優雅的解決方案!我喜歡! – tyranitar

+0

幾天前我第一次在另一個問題/答案中看到它時,我很驚訝這種行爲。我認爲這是值得自己的問題。 –

+0

在選擇列表中的確有[generate_subscripts的兩個例子](http://www.postgresql.org/docs/current/static/functions-srf.html),其中一個進行交叉連接。所以我想這是留在這裏。 –

0
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 
     ;