将动态参数传递给交叉表子查询
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
lateral
和format
:
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 | | |
我有 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
lateral
和format
:
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 | | |