查询父表并获取子表列

fre*_*111 5 postgresql database-design select inheritance

我有两张表,一张继承了另一张:

CREATE TABLE parent (
    col1 INTEGER
);

CREATE TABLE child (
    col2 INTEGER
) INHERITS( parent );

// Insert some data
INSERT INTO parent( col1 ) VALUES( 1 );
INSERT INTO child( col1, col2 ) VALUES( 2, 2 );
Run Code Online (Sandbox Code Playgroud)

有什么方法可以查询父表,使其获取子表的所有列?

此查询仅返回父列:

SELECT * FROM parent;

| col1 |
| ---- |
| 1    |
| 2    |
Run Code Online (Sandbox Code Playgroud)

我想要的查询将返回父和子中的所有列:

SELECT ...  -- some query, with desired result:

| col1 | col2 |
| ---- | ---- |
| 1    | NULL |
| 2    | 2    |
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 5

只要继承的列值集在所有表中都是唯一的,就有一个简单的NATURAL连接解决方案(此子句的罕见用例之一!):

SELECT * FROM ONLY parent NATURAL FULL JOIN child;
Run Code Online (Sandbox Code Playgroud)

因为NATURAL是(根据文档):

...USING列出两个表中具有相同名称的所有列的列表的简写。

每列只获得一次而无需显式SELECT列表,并且父表中的行使用 NULL 值扩展为添加的列 - 正是您想要的方式。

这甚至适用于任何列中的 NULL 值。


要同时查看结果中每一行原点,请插入另一行以演示差异:

INSERT INTO child(col1) VALUES(1);
Run Code Online (Sandbox Code Playgroud)

然后:

SELECT COALESCE(p.tableoid, c.tableoid)::regclass AS tbl, *
FROM   ONLY parent p NATURAL FULL JOIN child c;

 tbl   | col1 | col2
-------+------+----
parent | 1    | NULL
child  | 1    | NULL
child  | 2    | 2
Run Code Online (Sandbox Code Playgroud)

带有更多测试行的SQL Fiddle


如果所有子表中的所有附加列名称都是唯一的,则可以通过这种方式连接到多个子表。否则,您必须拼出一个明确的SELECT列表和明确的连接条件。

继承的列集在所有子表中必须是唯一的。