PostgreSQL:从连接表中获取所有子项

时间:2017-07-11 22:44:46

标签: sql postgresql

我的查询看起来像这样:

SELECT u.name, d.title, c.name
FROM documents d 
INNER JOIN publications p ON p.document_id = d.id
INNER JOIN components c ON p.component_id = c.id
INNER JOIN users u ON d.user_id = u.id

我的问题是,这只会在c.name可以有多个documentscomponents时返回第一个publications。我需要迭代每个document并获取所有他们的publications,然后通过每个出版物的组件获取标题。

我尝试过如下声明:

WITH child_publications AS (
    SELECT c.name, c.id
    FROM publications p
    INNER JOIN components c ON p.component_id = c.id
)

但我不太确定如何使用它们。出版物看起来像这样:

    Column    |  Type   |                         Modifiers                         | Storage | Stats target | Description 
--------------+---------+-----------------------------------------------------------+---------+--------------+-------------
 id           | integer | not null default nextval('publications_id_seq'::regclass) | plain   |              | 
 document_id  | integer |                                                           | plain   |              | 
 component_id | integer |                                                           | plain   |              | 

这样的组件:

            Column             |            Type             |                        Modifiers                        | Storage  | Stats target | Description 
-------------------------------+-----------------------------+---------------------------------------------------------+----------+--------------+-------------
 id                            | integer                     | not null default nextval('components_id_seq'::regclass) | plain    |              | 
 name                          | character varying           |                                                         | extended |              | 
 body                          | text                        |                                                         | extended |              | 

这样的文件:

        Column         |            Type             |                       Modifiers                        | Storage  | Stats target | Description 
-----------------------+-----------------------------+--------------------------------------------------------+----------+--------------+-------------
 id                    | integer                     | not null default nextval('documents_id_seq'::regclass) | plain    |              | 
 message               | text                        |                                                        | extended |              | 
 created_at            | timestamp without time zone | not null                                               | plain    |              | 
 updated_at            | timestamp without time zone | not null                                               | plain    |              | 
 title                 | character varying           |                                                        | extended |              | 
 user_id               | integer                     | not null                                               | plain    |              | 

列名代表他们持有的数据,我不确定DDL是什么。

1 个答案:

答案 0 :(得分:1)

INNER JOINS将结果限制为仅满足所有连接条件的行。 OUTER JOIN删除它并允许ALL ROWS FROM文档(在此查询中)。最常见的外连接是LEFT OUTER JOIN,如下所示:

SELECT u.name, d.title, c.name
FROM documents d 
LEFT OUTER JOIN publications p ON p.document_id = d.id
LEFT OUTER JOIN components c ON p.component_id = c.id
LEFT OUTER JOIN users u ON d.user_id = u.id

"缺点"对此你可能现在在结果中得到NULL。

" OUTER"在SQL语法中是可选的,因此您可以使用以下内容,它将是相同的结果:

SELECT u.name, d.title, c.name
FROM documents d 
LEFT JOIN publications p ON p.document_id = d.id
LEFT JOIN components c ON p.component_id = c.id
LEFT JOIN users u ON d.user_id = u.id