有没有办法将该子选择存储为表中的伪列?
一个VIEW
like被建议是一个完全有效的解决方案。去吧。
但是还有另一种更适合您的问题的方法。您可以编写一个将表类型作为参数的函数来模拟“计算字段”或“生成的列”。
考虑这个来自您的描述的测试用例:
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,1,5), (2,1,5), (3,1,1)
, (4,2,8), (5,2,8), (6,2,6)
, (7,3,11), (8,3,11), (9,3,11);
创建模拟的函数col3
:
CREATE FUNCTION col3(tbl_a)
RETURNS int8
LANGUAGE sql STABLE AS
$func$
SELECT sum(colx)
FROM tbl_b b
WHERE b.a_id = $1.a_id
$func$;
现在可以查询:
SELECT a_id, col1, col2, tbl_a.col3
FROM tbl_a;
甚至:
SELECT *, a.col3 FROM tbl_a a;
注意我是如何写tbl_a.col3
/a.col3
的,而不仅仅是col3
. 这是必不可少的。
与Oracle 中的“虚拟列”不同,它不会自动包含在SELECT * FROM tbl_a
. 你可以使用 a VIEW
。
为什么这行得通?
引用表列的常用方法是使用属性表示法:
从 tbl_a 中选择tbl_a.col1;
调用函数的常用方法是使用函数表示法:
选择col3(tbl_a) ;
一般来说,最好坚持这些符合 SQL 标准的规范方式。
但是 Postgres 也允许使用属性表示法。这些也有效:
从 tbl_a 中选择col1(tbl_a);
选择tbl_a.col3;
更多关于手册中的内容。
你现在可能已经看到了,这是怎么回事。这看起来像你会添加一个额外的表列,tbl_a
而col3()
实际上是一个函数,它将当前行tbl_a
(或其别名)作为行类型参数并计算一个值。
SELECT *, a.col3
FROM tbl_a AS a;
如果存在实际列col3
,则它具有优先权,并且系统不会以该行tbl_a
作为参数来查找该名称的函数。
它的“美”:您可以添加或删除列,tbl_a
最后一个查询将动态返回所有当前列,其中视图只会返回在创建时存在的列(早期绑定与后期绑定*
)。
当然,您现在必须先删除依赖函数,然后才能删除表。并且在对表进行更改时,您必须注意不要使函数无效。
我还是不会用。这对无辜的读者来说太令人惊讶了。