用于比较复合键的简写表示法(在PostgreSQL中)

时间:2016-08-18 13:33:10

标签: sql foreign-keys primary-key postgresql-9.5

我有两张桌子:

CREATE TABLE a (a1 TEXT, a2 INTEGER, a3 INTEGER,
  PRIMARY KEY (a2, a3));
CREATE TABLE b (b1 TEXT, b2 INTEGER, b3 INTEGER,
  FOREIGN KEY (b2, b3) REFERENCES a);

我想为a1a中至少有一行引用的行获取b。例如。像这样:

SELECT a1 FROM a 
WHERE EXISTS (SELECT * FROM b WHERE a.a2 = b.b2 AND a.a3 = b.b3);

是否有一种更短(且更有效)的方式来表达这一点,最好是一种不需要我明确列出复合键中所有列的方法,因为该列表可能会改变?

1 个答案:

答案 0 :(得分:2)

你可以在Postgres做的一个捷径是:

SELECT a1
FROM a
WHERE (a.a2, a.a3) IN (SELECT b.b2, b.b3 FROM b) ;

当然,您仍然需要列出密钥。

如果b没有重复项,如果列名相同,您可以这样做:

SELECT a1
FROM a JOIN
     b
     USING (a2, a3);

使用USING,您只需列出一次密钥。

我毫不犹豫地这样说,但你也可以使用NATURAL JOIN进一步减少这一点,假设公用密钥具有相同的名称​​且没有其他列具有相同的名称

SELECT a1
FROM a NATURAL JOIN
     b;

但是,强烈阻止使用NATURAL JOIN,因为它使用两个具有相同名称的表中的所有列。它不尊重声明的外键关系,因此它可以返回意外的结果。