Има ли начин да съхраните този подселекция като псевдоколона в таблицата?
A 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
. Можете да използвате VIEW
за това.
Защо това работи?
Често срещаният начин за препратка към колона на таблица е с нотация на атрибут :
SELECT tbl_a.col1 FROM tbl_a;
Често срещаният начин за извикване на функция е с функционална нотация :
SELECT col3(tbl_a);
Като цяло е най-добре да се придържате към тези канонични начини , които са в съответствие със стандарта SQL.
Но Postgres също позволява записване на атрибути. Тези също работят:
SELECT col1(tbl_a) FROM tbl_a; SELECT tbl_a.col3;
Повече за това в ръководството.
Сигурно вече сте виждали накъде води това. Това изглежда както бихте добавили допълнителна колона от таблица tbl_a
докато col3()
всъщност е функция, която приема текущия ред на tbl_a
(или неговия псевдоним) като аргумент за тип ред и изчислява стойност.
SELECT *, a.col3
FROM tbl_a AS a;
Ако има действителна колона col3
той има приоритет и системата не търси функция с това име, като заема реда tbl_a
като параметър.
"Красотата" на това:можете да добавяте или пускате колони от tbl_a
и последната заявка ще върне динамично всички текущи колони, където изгледът ще върне само такива колони, които са съществували по време на създаване (ранно обвързване срещу късно обвързване на *
).
Разбира се, трябва да махнете зависимата функция, преди да можете да пуснете таблицата сега. И трябва да внимавате да не отмените функцията, когато правите промени в таблицата.
Все още не бих го използвал. Твърде изненадващо е за невинния читател.