sql >> Database >  >> RDS >> PostgreSQL

Algemene zoekopdracht opslaan als kolom?

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.



  1. Een gebruiker maken en machtigingen verlenen in Oracle

  2. Het object 'DF__*' is afhankelijk van kolom '*' - Veranderen in int in double

  3. JSON_MODIFY() Voorbeelden in SQL Server (T-SQL)

  4. Expliciete JOINs vs Impliciete joins?