postgresql – 将公共查询存储为列?

使用PostgreSQL,我有一些看起来像这样的查询:
SELECT <col 1>,<col 2>,(SELECT sum(<col x>)
        FROM   <otherTable> 
        WHERE  <other table foreignkeyCol>=<this table keycol>) AS <col 3>
FROM   <tbl>

假定子选择在每种情况下都是相同的,有没有办法将该子选择作为伪列存储在表中?基本上,我想能够从表A中选择一个列,该列是来自表B中记录相关的特定列的总和。这可能吗?

Is there a way to store that sub-select as a pseudo-column in the table?

一个VIEW喜欢被建议是一个完全有效的解决方案。但还有另一种方式更适合你的问题。您可以编写一个函数,将表类型作为参数来模拟“计算字段”或“生成列”。

考虑这个测试用例,源自您的描述:

CREATE TABLE tbl_a (a_id int,col1 int,col2 int);
INSERT INTO tbl_a VALUES (1,1,1),(2,2,2),(3,3,3),(4,4,4);

CREATE TABLE tbl_b (b_id int,a_id int,colx int);
INSERT INTO tbl_b VALUES
 (1,5),8),(5,(6,6),(7,11),(8,(9,11);

创建模仿col3的函数:

CREATE FUNCTION col3(tbl_a)
  RETURNS int8 AS
$func$
    SELECT sum(colx)
    FROM   tbl_b b
    WHERE  b.a_id = $1.a_id
$func$ LANGUAGE SQL STABLE;

现在可以查询:

SELECT a_id,col1,col2,tbl_a.col3
FROM   tbl_a;

甚至:

SELECT *,a.col3 FROM tbl_a a;

注意我如何写tbl_a.col3 / a.col3,而不只是col3。这是必要的。

“virtual column” in Oracle不同,它不会自动包含在SELECT * FROM tbl_a中。你可以使用VIEW。

为什么这个工作?

引用表列的常见方法是使用属性符号:

SELECT tbl_a.col1 FROM tbl_a;

调用函数的常用方法是使用函数表示法:

SELECT col3(tbl_a);

一般来说,最好坚持这些规范的方式,这符合SQL标准。

但在PostgreSQL中,函数符号和属性符号是等价的。所以这些工作以及:

SELECT col1(tbl_a) FROM tbl_a;
SELECT tbl_a.col3;

More about that in the manual.
你现在可能看到,这是怎么回事。这看起来像你会添加表tbl_a的额外的列,而col3()实际上是一个函数,它将tbl_a(或其别名)的当前行作为行类型参数,并计算一个值。

SELECT *,a.col3
FROM   tbl_a AS a;

如果有一个实际的列col3,它优先,系统不会查找该行的函数tbl_a作为参数。

它的美妙之处在于:您可以从tbl_a添加或删除列,最后一个查询将动态返回所有当前列,其中视图只返回创建时存在的列(早期绑定与*的早期绑定)。当然,你必须删除自定义函数,然后才能删除表。并且,在更改表时,必须注意不要使函数无效。

相关文章

文章浏览阅读601次。Oracle的数据导入导出是一项基本的技能,...
文章浏览阅读553次。开头还是介绍一下群,如果感兴趣polardb...
文章浏览阅读3.5k次,点赞3次,收藏7次。折腾了两个小时多才...
文章浏览阅读2.7k次。JSON 代表 JavaScript Object Notation...
文章浏览阅读2.9k次,点赞2次,收藏6次。navicat 连接postgr...
文章浏览阅读1.4k次。postgre进阶sql,包含分组排序、JSON解...