将动态参数传递给交叉表子查询

Pass dynamic parameter to crosstab subquery

我有 table 喜欢那里:

 table:
 | id | key  | label  | amount |
 |----|------|--------|--------|
 | 1  | 1    | label1 | 10     |
 | 2  | 1    | label2 | 15     |
 | 3  | 1    | label3 | 99     |
 | 4  | 2    | label4 | 33     |
 | 5  | 2    | label2 | 10     |

fkey 是其他 table.

的外键

我需要在交叉表中使用结果并为这些保留空值,其中没有关系:

select * from crosstab(
   'with labels (lbl) as ( ' ||
   '  values (''label2''), (''label3''), (''label4'') ' ||
   ') ' ||
   'select 1, l.lbl, t.amount ' || 
   'from labels l ' ||
   '  left outer join "table" t on l.lbl = t.label and t.key = 1 ' ||
   'order by l.lbl' ) AS (
fkey integer, label1 integer, label2 integer, label3 integer)

结果如我所料(key = 1):

 |    | key  | label2 | label3 | label4 |
 |----|------|--------|--------|--------|
 | 1  | 2    | 15     | 99     | NULL   |

键 = 2

select * from crosstab(
   'with labels (lbl) as ( ' ||
   '  values (''label2''), (''label3''), (''label4'') ' ||
   ') ' ||
   'select 2, l.lbl, t.amount ' || 
   'from labels l ' ||
   '  left outer join "table" t on l.lbl = t.label and t.key = 2 ' ||
   'order by l.lbl' ) AS (
fkey integer, label1 integer, label2 integer, label3 integer)

结果是:

 |    | key  | label2 | label3 | label4 |
 |----|------|--------|--------|--------|
 | 1  | 2    | 10     | NULL   | 33     |

select 1, l.lbl, t.amount 中的返回键是硬编码的,因为如果没有关系我需要保留查询键(因为 t.key 返回 NULL)。

现在我需要将此查询用作数据库中每个键的子查询。所以我需要类似的东西:

with keys(key) as (
  values (1), (2), (3)
)
select * from keys
  left join (select * from crosstab(
    'with labels (lbl) as ( ' ||
    '  values (''label2''), (''label3''), (''label4'') ' ||
    ') ' ||
    'select ??, l.lbl, t.amount ' || 
    'from labels l ' ||
    '  left outer join "table" t on l.lbl = t.label and t.key = ?? ' ||
    'order by l.lbl' ) AS (
      key integer, label1 integer, label2 integer, label3 integer
    )
 ) I on (keys.key = I.key)

有没有办法将密钥绑定到 ?? 标记的位置?

这是测试人员 http://rextester.com/JMUBI41337(?? 中的 2 表示仅当密钥为 2 时才有效)。

预期结果:

 |    | key  | label2 | label3 | label4 |
 |----|------|--------|--------|--------|
 | 1  | 1    | 15     | 99     | NULL   |
 | 2  | 2    | 10     | NULL   | 33     |
 | 3  | 3    | NULL   | NULL   | NULL   |

已解决。 Link 到 Clodoaldo Neto 的工作解决方案:http://rextester.com/SYWQ20694

lateralformat:

select *
from
    (values (1),(2),(3)) keys(key)
    left join lateral (
        select * from crosstab(format($$
            with labels (lbl) as (values
                ('label2'), ('label3'), ('label4')
            )
            select %1$s, l.lbl, t.amount
            from
                labels l
                left outer join
                t on l.lbl = t.label and t.key = %1$s
            order by l.lbl
        $$, keys.key)) as (
            key integer, label2 integer, label3 integer, label4 integer
        )
    ) i using (key)
;
 key | label2 | label3 | label4 
-----+--------+--------+--------
   1 |     15 |     99 |       
   2 |     10 |        |     33
   3 |        |        |