Is er een manier om die subselectie op te slaan als een pseudo-kolom in de tabel?
Een VIEW
zoals is geadviseerd is een perfect geldige oplossing. Ga ervoor.
Maar er is een andere manier die nog beter aansluit bij uw vraag. U kunt een functie schrijven die het tabeltype als parameter meeneemt om emuleren een "berekend veld" of "gegenereerde kolom" .
Beschouw deze testcase, afgeleid van uw beschrijving:
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);
Functie maken die col3
emuleert :
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$;
Nu kunt u het volgende opvragen:
SELECT a_id, col1, col2, tbl_a.col3
FROM tbl_a;
Of zelfs:
SELECT *, a.col3 FROM tbl_a a;
Merk op hoe ik tbl_a.col3
. schreef / a.col3
, niet alleen col3
. Dit is essentieel .
In tegenstelling tot een "virtuele kolom" in Oracle is het niet automatisch opgenomen in een SELECT * FROM tbl_a
. Je zou een VIEW
. kunnen gebruiken daarvoor.
Waarom werkt dit?
De gebruikelijke manier om naar een tabelkolom te verwijzen is met attribuutnotatie :
SELECT tbl_a.col1 FROM tbl_a;
De gebruikelijke manier om een functie aan te roepen is met functionele notatie :
SELECT col3(tbl_a);
Over het algemeen is het het beste om vast te houden aan deze canonieke manieren , die overeenkomen met de SQL-standaard.
Maar Postgres staat ook attribuutnotatie toe. Deze werken ook:
SELECT col1(tbl_a) FROM tbl_a; SELECT tbl_a.col3;
Daarover meer in de handleiding.
Je ziet nu waarschijnlijk wel waar dit heen gaat. Dit ziet eruit alsof je een extra kolom van tabel tbl_a
. zou toevoegen terwijl col3()
is eigenlijk een functie waaraan de huidige rij van tbl_a
. moet doorgegeven worden (of zijn alias) als argument voor rijtype en berekent een waarde.
SELECT *, a.col3
FROM tbl_a AS a;
Als er een echte kolom is col3
het heeft prioriteit en het systeem zoekt niet naar een functie met die naam in de rij tbl_a
als parameter.
De "schoonheid" ervan:je kunt kolommen toevoegen of verwijderen uit tbl_a
en de laatste query retourneert dynamisch alle huidige kolommen, waarbij een weergave alleen kolommen retourneert die bestonden op het moment van aanmaak (vroege binding versus late binding van *
).
Natuurlijk moet je de afhankelijke functie laten vallen voordat je de tabel nu kunt laten vallen. En u moet ervoor zorgen dat u de functie niet ongeldig maakt wanneer u wijzigingen aanbrengt in de tabel.
Ik zou het nog steeds niet gebruiken. Het is te verrassend voor de onschuldige lezer.