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.