查询中组合外键/主键的列上的联接表

问题描述 投票:21回答:2
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)
);

在给定特定订阅的情况下,查询送货的好方法是什么?有没有一种方法可以将列名分配给PRIMARY KEY (magazine_id, user_id)和相应的外键,以便我可以像这样查询:

SELECT *
FROM subscription
JOIN delivery ON (delivery.subscription_fk = delivery.subscription_pk);

注意:我可以这样写:

SELECT *
FROM subscription
JOIN delivery ON (delivery.magazine_id = subscription.magazine_id
              AND delivery.user_id = subscription.user_id);

但是,我给人的印象是,实现这一目标的方式不太冗长。

sql postgresql join natural-join
2个回答
29
投票

NATURAL JOIN

SELECT *
FROM   subscription
NATURAL JOIN delivery;

引用the manual on SELECT

SELECT

[NATURALNATURAL列表的简写,其中提到两个表中具有相同名称的所有列。

它可以用于您的测试设置,但是不是严格按照您的要求进行。该连接基于共享相同名称的所有列。不考虑外键。 USING是个好主意的情况很少。

简化代码/不那么冗长

对于初学者,您可以使用表别名,并且不需要在带有NATURAL JOIN的连接条件周围加括号(与ON不同):

USING

由于联接条件中的列名称相同,因此可以使用SELECT * FROM subscription s JOIN delivery d ON d.magazine_id = s.magazine_id AND d.user_id = s.user_id; 进一步简化:

USING

没有语法变量会自动基于外键约束进行联接。您将不得不查询系统目录并动态构建SQL。


1
投票

SELECT * FROM subscription s JOIN delivery d USING (magazine_id, user_id); 是否没有两列代表外键?然后,它将像使用非复合主键delivery一样工作。

© www.soinside.com 2019 - 2024. All rights reserved.