Postgres:从父表和所有子表中选择数据

时间:2012-02-02 14:58:35

标签: sql postgresql

我有一个父表和几个子表,它们的结构与父表和彼此略有不同。我可以组装一个查询,从父表和所有子表中获取所有其他列的数据吗?

3 个答案:

答案 0 :(得分:1)

使用正确的模式并使用INHERITS告诉PostgreSQL结构:

CREATE TABLE foo(x int);

CREATE TABLE bar(y int) INHERITS (foo); -- <===

INSERT INTO foo(x) VALUES(1); -- one record
INSERT INTO bar(x,y) VALUES(2,3); -- one record

SELECT * FROM foo; -- two results

SELECT * FROM ONLY foo; -- one result, see ONLY

http://www.postgresql.org/docs/current/interactive/ddl-inherit.html

答案 1 :(得分:1)

您似乎需要使用左外连接。同样,不是一个理想的解决方案,可能会改变数据库的结构会更好,但仍然是:

CREATE TABLE foo(x int);

CREATE TABLE bar(y int) INHERITS (foo);

INSERT INTO foo(x) VALUES(1);
INSERT INTO bar(x,y) VALUES(2,3);

SELECT foo.*, bar.y 
FROM foo LEFT OUTER JOIN bar ON (foo.x = bar.x);

父项中的条目对y具有null,必须将其考虑在内,但它确实会提取所有数据。这里的缺点是你需要专门命名子表中的额外列。 (尽管我发现最好避免在进入代码的查询中使用*。无论如何。)

如果您真的不想为子表中的列命名,那么有一篇文章介绍如何选择除某些列here以外的所有列。你可以弄清楚如何将两者放在一起。

编辑:

如果y可以设置为null,并且区分什么是合法的条y null和非ligitimate foo y null很重要,你可以尝试这样做:

SELECT 'foo' AS from_table, *, NULL::int AS y
FROM ONLY foo

UNION

SELECT 'bar' AS from_table, *
FROM bar;

然后在代码端,您可以使用from table列来处理来自where的内容,并告诉哪些null y值是合法的,哪些不合法。

答案 2 :(得分:0)

简单的答案是你不能轻易做到这一点。你不能有锯齿状的行(与Informix不同),因此一个简单的选择方法是行不通的。

您可能能够以编程方式创建一个使用row_to_json和一堆联合语句的查询,但这是很多工作,非常复杂,可能不是您想要的。它也无法解决列可能具有相同名称但在不同子表中具有不同含义的情况。

总的来说,我认为你需要在这里重新考虑你的方法。如果你正在尝试依赖锯齿状的行,你的应用程序和数据库之间会有很多非常松散的契约,因此你将有很多潜在的独特问题。

这里最好的方法是将额外的列移到连接表中,您可以使用left join来检索它们。