【发布时间】:2012-02-02 14:58:35
【问题描述】:
我有一个父表和几个子表,它们的结构与父表和彼此的结构略有不同。我可以组装一个查询,从父表和所有子表中获取所有数据以及所有附加列吗?
【问题讨论】:
-
发布表格结构、示例行以及您想要的结果。
-
jQuery 是从哪里来的?
标签: sql postgresql
我有一个父表和几个子表,它们的结构与父表和彼此的结构略有不同。我可以组装一个查询,从父表和所有子表中获取所有数据以及所有附加列吗?
【问题讨论】:
标签: sql postgresql
使用适当的模式并使用 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
【讨论】:
bar,则类似SELECT * FROM foo WHERE x=?; 的查询将返回带有x 和y 列的结果。
看来您在这里需要的是使用左外连接。同样,这不是一个理想的解决方案,并且可能对数据库的结构进行更改会更好,但仍然是:
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 并且区分什么是合法的 bar y null 和非合法的 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 列来处理来自哪里的内容,并判断哪些 null y 值是合法的,哪些不是。
【讨论】:
简单的答案是你不能轻易做到这一点。您不能有锯齿状的行(与 Informix 不同),因此简单的选择方法行不通。
您可能能够以编程方式创建一个使用 row_to_json 和一堆联合语句的查询,但这需要大量工作、非常复杂,而且可能不是您想要的。它也无法解决列在不同子表中可能具有相同名称但含义不同的情况。
总的来说,我认为您需要在这里重新考虑您的方法。如果您尝试依赖锯齿状行,那么您的应用程序和数据库之间将有很多非常松散的契约,因此您将有很多潜在的独特问题。
这里最好的方法是将多余的列移到连接表中,您可以使用left join 来检索它们。
【讨论】: