【问题标题】:PostgreSQL join to denormalize a table with generate_seriesPostgreSQL 连接以使用 generate_series 对表进行非规范化
【发布时间】:2012-09-25 09:11:44
【问题描述】:

我有这张桌子:

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

我想以这种方式“去规范化”行:

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

所以每个名称的行数等于 count 列:我有 4 行 john,2 行 mark,3 行 albert。 但是如果我不知道最高计数(在本例中为 4),我将无法使用 generate_series() 函数。有没有办法在不知道 MAX(count) 的情况下做到这一点?

【问题讨论】:

    标签: postgresql join denormalization generate-series


    【解决方案1】:
    select name, 
           generate_series(1,count)
    from mytable;
    

    集合返回函数可以在select 列表中使用,并将与从基表中检索到的行进行交叉连接。

    认为这是一种未记录的行为,将来可能会消失,但我不确定(我记得在邮件列表中对此进行了一些讨论)

    SQLFiddle example

    【讨论】:

    • 非常优雅的解决方案!我喜欢!
    • 几天前我第一次在另一个问题/答案中看到这种行为时,我感到很惊讶。我认为值得自己提出问题。
    • 选择列表中确实有two examples of generate_subscripts,其中一个在进行交叉连接。所以我想它会留下来。
    【解决方案2】:
    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
            ;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-08
      • 2013-01-08
      • 2013-06-30
      • 1970-01-01
      • 2016-11-12
      • 2017-05-02
      • 2011-12-18
      • 2020-10-22
      相关资源
      最近更新 更多