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

然而,我的印象是,有一种不那么冗长的方式来实现这一点.

推荐答案

有一个NATURAL JOIN:

SELECT *
FROM   subscription
NATURAL JOIN delivery;

引用the manual on SELECT:

NATURAL

NATURALUSING列表的简写,其中提到了两个表中具有相同名称的所有列.

它可以用于你的测试设置,但它是not strictly doing what you ask for.连接基于共享相同名称的所有列.不考虑外键.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进一步简化:

SELECT *
FROM   subscription s
JOIN   delivery     d USING (magazine_id, user_id);

没有基于外键约束自动进行连接的语法变体.您必须查询系统目录并动态构建SQL.

Postgresql相关问答推荐

Postgs密码重置问题

将几个左连接合并为一个

PostgreSQL按描述请求

Select 所有数组类型和维度

如何将存储的、生成的列添加到非常大的表中?

为什么 Postgres 中的 now() 和 now()::timestamp 对于 CET 和 CEST 时区如此错误?

supabase 中的交易

在Postgres中如何连接具有相同名称列的表并更改列名称?

使用 OpenCypher 和 Apache AGE 在两个顶点之间创建双向关系

如何创建一个触发器来传播对主键表的更新?

如何计算过滤器中的百分比

推送到 Heroku 时出现带有 Postgres 的 Rails 迁移错误

PostgreSQL 查询到 Excel 表

PostgreSQL 中基于时间戳的移动平均线

?(问号)运算符在 Rails 中查询 Postgresql JSONB 类型

错误:CASE types character varying and numeric cannot be matched

错误:ERROR: table name specified more than once

避免通过 JPA 将null值插入数据库表

PostgreSQL regexp_replace() 只保留一个空格

PL/pgSQL 中的 BREAK 语句