gpt4 book ai didi

postgresql - 使用动态目标列进行查询

转载 作者:行者123 更新时间:2023-11-29 12:16:38 26 4
gpt4 key购买 nike

我正在尝试在 Postgres 中构建一个 View ,该 View 使用 3 个表的数据。我不确定这是否可行,并且在谷歌上搜索了一下,但没有找到任何结论。这就是我正在尝试做的:

我有一个项目名称表 - 假设有 5 个项目:

水果

id | name
1 | banana
2 | orange
3 | pear
4 | apple
5 | grape

然后我有一个人的名单

id  |  name
1 | Joe Blow
2 | Sally Smith
3 | John Jones
4 | Sam Benny
5 | Nick Stevens
6 | Peter Sandwitch
7 | Sarah Morgan

然后我有第三个表链接上面的两个:

people_fruits

person_id | fruit_id
1 | 1
1 | 2
1 | 3
1 | 4
2 | 1
2 | 3
3 | 5
6 | 3
7 | 3
7 | 4

我想要做的是能够利用上面的内容动态创建一个 View ,该 View 将根据水果表的内容更改列。例如,我希望 View 按如下方式显示上述数据:

my_fruity_view

name            | bananna | orange | pear | apple | grape
Joe Blow | X | X | X | X |
Sally Smith | X | | X | |
John Jones | | | | | X
Sam Benny | | | | |
Nick Stevens | | | | |
Peter Sandwitch | | | X | |
Sarah Morgan | | | X | X |

然后,如果我稍后添加水果芒果,下次运行查询时(无需修改),它会将其添加为一列:

my_fruity_view

name            | bananna | orange | pear | apple | grape | mango
Joe Blow | X | X | X | X | |
Sally Smith | X | | X | | |
John Jones | | | | | X |
Sam Benny | | | | | |
Nick Stevens | | | | | |
Peter Sandwitch | | | X | | |
Sarah Morgan | | | X | X | |

这样的查询可能吗?我在堆栈溢出时看到了一些这样的事情 - 但它似乎是在每列的基础上完成的 - 但我的数据需要是动态的。

我可以通过编程实现这一点,但我更愿意将其打包到一个 View 中以保持整洁。如有任何帮助,我们将不胜感激。

最佳答案

基本上,您需要一个数据透视表 或一个交叉表。附加模块 tablefunc 提供了您需要的功能。如果您不熟悉它,请先阅读此内容:

你的案例的特殊困难:你首先需要一个连接表的查询来产生正确的输入:

SELECT p.name, f.name, text 'x' AS marker -- required, logically redundant column
FROM people p
LEFT JOIN people_fruits pf ON pf.person_id = p.id -- LEFT JOIN !
LEFT JOIN fruits f ON f.id = pf.fruit_id
ORDER BY p.id, f.id; -- seems to be the desired sort order

LEFT [OUTER] JOIN,这样你就不会无果而失人。

crosstab() 函数中使用它,采用 两个 参数,如下所示:

SELECT * FROM crosstab(
$$SELECT p.name, f.name, text 'x'
FROM people p
LEFT JOIN people_fruits pf ON pf.person_id = p.id
LEFT JOIN fruits f ON f.id = pf.fruit_id
ORDER BY p.id$$
,$$VALUES ('bananna'), ('orange'), ('pear'), ('apple'), ('grape')$$)
AS ct (name text, bananna text, orange text, pear text, apple text, grape text);

目标列列表中的水果顺序必须与第二个参数中的水果顺序相匹配(在您的情况下按 id 排序)。

缺少的水果会得到一个 NULL 值。

但是,这还不是动态。 SQL 绝对不可能完全动态,它需要在调用时知道结果列。无论哪种方式,您都需要两次往返数据库服务器。您可以让 Postgres 动态构建交叉表查询,然后在下一步中执行它。

带有代码示例的相关答案:

一个替代方法是返回一个包含的数组或文档类型(jsonxml、...) 元素的动态列表。

关于postgresql - 使用动态目标列进行查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50574762/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com