PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Stocker la requête commune en tant que colonne ?

Existe-t-il un moyen de stocker cette sous-sélection en tant que pseudo-colonne dans le tableau ?

Une VIEW comme cela a été conseillé est une solution parfaitement valable. Allez-y.

Mais il existe un autre moyen qui correspond encore plus à votre question. Vous pouvez écrire une fonction qui prend le type de table comme paramètre pour émuler un "champ calculé" ou "colonne générée" .

Considérez ce cas de test, dérivé de votre description :

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);

Créer une fonction qui émule 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$;

Vous pouvez maintenant interroger :

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

Ou encore :

SELECT *, a.col3 FROM tbl_a a;

Notez comment j'ai écrit tbl_a.col3 / a.col3 , pas seulement col3 . C'est essentiel .

Contrairement à une "colonne virtuelle" dans Oracle, ce n'est pas inclus automatiquement dans un SELECT * FROM tbl_a . Vous pouvez utiliser un VIEW pour ça.

Pourquoi ça marche ?

La manière courante de référencer une colonne de table est d'utiliser la notation d'attribut :

SELECT tbl_a.col1 FROM tbl_a;

La façon courante d'appeler une fonction est d'utiliser la notation fonctionnelle :

SELECT col3(tbl_a);

Généralement, il est préférable de s'en tenir à ces méthodes canoniques , qui sont conformes au standard SQL.

Mais Postgres permet également la notation d'attribut. Ceux-ci fonctionnent également :

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

Plus d'informations à ce sujet dans le manuel.
Vous voyez probablement maintenant où cela nous mène. Cela semble comme si vous ajoutiez une colonne supplémentaire de la table tbl_a tandis que col3() est en fait une fonction qui prend la ligne courante de tbl_a (ou son alias) comme argument de type de ligne et calcule une valeur.

SELECT *, a.col3
FROM   tbl_a AS a;

S'il y a une colonne réelle col3 elle est prioritaire et le système ne recherche pas une fonction de ce nom prenant la ligne tbl_a comme paramètre.

La "beauté" de celui-ci :vous pouvez ajouter ou supprimer des colonnes de tbl_a et la dernière requête renverra dynamiquement toutes les colonnes actuelles, où une vue ne renverrait que les colonnes qui existaient au moment de la création (liaison précoce vs liaison tardive de * ).
Bien sûr, vous devez supprimer la fonction dépendante avant de pouvoir supprimer la table maintenant. Et vous devez faire attention à ne pas invalider la fonction lorsque vous apportez des modifications à la table.

Je ne l'utiliserais toujours pas. C'est trop surprenant pour le lecteur innocent.