CREATE TABLE subscription (
magazine_id bigint,
user_id bigint,
PRIMARY KEY (magazine_id, user_id)
);
CREATE TABLE delivery (
magazine_id bigint,
user_id bigint,
FOREIGN KEY (subscription) REFERENCES subscription (magazine_id, user_id)
);
Quelle est la bonne façon de rechercher des livraisons avec un abonnement particulier? Existe-t-il un moyen d'attribuer un nom de colonne à PRIMARY KEY (magazine_id, user_id)
et la clé étrangère correspondante afin que je puisse interroger comme ceci:
SELECT *
FROM subscription
JOIN delivery ON (delivery.subscription_fk = delivery.subscription_pk);
Remarque: je peux écrire quelque chose comme ceci:
SELECT *
FROM subscription
JOIN delivery ON (delivery.magazine_id = subscription.magazine_id
AND delivery.user_id = subscription.user_id);
Cependant, j'ai l'impression qu'il existe un moyen moins verbeux d'y parvenir.
Il y a un NATURAL JOIN
:
SELECT *
FROM subscription
NATURAL JOIN delivery;
Citer le manuel sur SELECT
:
NATURAL
NATURAL
est un raccourci pour une listeUSING
qui mentionne toutes les colonnes des deux tables qui portent les mêmes noms.
Cela fonctionnerait pour votre configuration de test, mais il ne fait pas strictement ce que vous demandez . La connexion est basée sur toutes les colonnes partageant le même nom. Les clés étrangères ne sont pas prises en compte. Les cas où NATURAL JOIN
est une bonne idée sont rares.
Pour commencer, vous pouvez utiliser des alias de table et vous n'avez pas besoin de parenthèses autour des conditions de jointure avec ON
(contrairement à USING
):
SELECT *
FROM subscription s
JOIN delivery d ON d.magazine_id = s.magazine_id
AND d.user_id = s.user_id;
Comme les noms de colonne dans les conditions de jointure sont identiques, vous pouvez simplifier davantage avec USING
:
SELECT *
FROM subscription s
JOIN delivery d USING (magazine_id, user_id);
Il n'y a pas de variante de syntaxe faisant automatiquement des jointures basées sur des contraintes de clé étrangère. Vous devrez interroger les catalogues système et créer le SQL dynamiquement.
delivery
n'a-t-il pas deux colonnes représentant la clé étrangère? Ensuite, cela devrait fonctionner comme avec une clé primaire non composite SELECT * FROM subscription JOIN delivery ON (delivery.magazine_id = subscription.magazine_id AND delivery.user_id = subscription.user_id)
.