SQL连接问题 - 加入两个相关查询(Full Outer Join)

时间:2012-03-29 16:34:39

标签: sql oracle

我几天来一直在与此作斗争。我不是SQL的专家,并设法创建了一些查询,但是我有一个真正的工作来加入查询。

例如,我想加入以下两个查询:

SELECT publication_id AS Pure_Publication_Id, caa.person_id, 
    caa.name_first_name AS Primary_Author_First_Name, 
    caa.name_last_name AS Primary_Author_Last_Name
FROM pure.classified_author_assoc caa
    LEFT OUTER JOIN Pure.Publication
        ON Caa.Publication_Id = Publication.Id
WHERE Caa.Person_Id  IS NOT NULL
    AND publication.id IN
    (
        SELECT DISTINCT pure.publication_project_assoc.publication_id
        FROM Pure.project
            JOIN Pure.Publication_project_assoc
                ON project.id = Pure.Publication_project_assoc.project_id
        WHERE pure.project.source_id IN ('XEP378', 'XES049', 'YAH001')
    )
GROUP BY publication_id, caa.person_id, caa.name_first_name, caa.name_last_name;

SELECT publication.id AS Pure_Publication_Id
    COUNT (person_id) AS "NUMBER_OF_AUTHORS", 
    CASE WHEN COUNT (person_id) > 1 THEN 'Yes' 
        else 'No' END AS Additional_Authors
FROM pure.classified_author_assoc caa
    LEFT OUTER JOIN Pure.Publication
        ON Caa.Publication_Id = Publication.Id
WHERE Caa.Person_Id  IS NOT NULL
    AND publication.id IN
    (
        SELECT DISTINCT pure.publication_project_assoc.publication_id
        FROM Pure.project
            JOIN Pure.Publication_project_assoc
                ON project.id = Pure.Publication_project_assoc.project_id
        WHERE pure.project.source_id IN ('XEP378', 'XES049', 'YAH001')
    )
GROUP BY publication.id;

我不能将它们组合在一个查询中(我不认为),因为第一个查询只返回Number_of_authors。但是,当我尝试运行查询将在中间完全连接如下,我得到一个SQL命令未正确结束错误在第一个sql语句结束时我不知道连接应该在什么端。

SELECT publication_id AS Pure_Publication_Id, caa.person_id, 
    caa.name_first_name AS Primary_Author_First_Name,
    caa.name_last_name AS Primary_Author_Last_Name
FROM pure.classified_author_assoc caa
    LEFT OUTER JOIN Pure.Publication
        ON Caa.Publication_Id = Publication.Id
WHERE Caa.Person_Id  IS NOT NULL
    AND publication.id IN
    (
        SELECT DISTINCT pure.publication_project_assoc.publication_id
        FROM Pure.project
            JOIN Pure.Publication_project_assoc
                ON project.id = Pure.Publication_project_assoc.project_id
        WHERE pure.project.source_id IN ('XEP378', 'XES049', 'YAH001')
    )
GROUP BY publication_id, caa.person_id, caa.name_first_name, caa.name_last_name
FULL OUTER JOIN
(
    SELECT publication.id AS Pure_Publication_Id, 
        COUNT (person_id) AS "NUMBER_OF_AUTHORS", 
        CASE WHEN COUNT (person_id) > 1 THEN 'Yes' 
            else 'No' END AS Additional_Authors
    FROM pure.classified_author_assoc caa
        LEFT OUTER JOIN Pure.Publication
            ON Caa.Publication_Id = Publication.Id
    WHERE Caa.Person_Id  IS NOT NULL
        AND publication.id IN
        (
            SELECT DISTINCT pure.publication_project_assoc.publication_id
            FROM Pure.project
                JOIN Pure.Publication_project_assoc
                    ON project.id = Pure.Publication_project_assoc.project_id
            WHERE pure.project.source_id IN ('XEP378', 'XES049', 'YAH001')
        )
)
GROUP BY publication.id
ON ****;

我已经尝试过每一种我能想到的方式,并且知道它应该是简单的东西。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

您必须将第二个查询加入第一个查询的FROM子句。在我看来,你可能真的在LEFT JOIN之后而不是一个完全加入。也许一个WITH子句可能会有所帮助:

WITH q AS (
(SELECT publication.id AS Pure_Publication_Id, COUNT (person_id) AS "NUMBER_OF_AUTHORS", CASE WHEN COUNT (person_id) > 1 THEN 'Yes' else 'No' END AS Additional_Authors
...
)
SELECT publication_id AS Pure_Publication_Id, caa.person_id, caa.name_first_name AS Primary_Author_First_Name, caa.name_last_name AS Primary_Author_Last_Name, q.NUMBER_OF_AUTHORS, q.additional_authors 
  FROM pure.classified_author_assoc caa 
          LEFT OUTER JOIN Pure.Publication ON Caa.Publication_Id = Publication.Id
          LEFT OUTER JOIN q ON publication_id = q.pure_publication_id
 WHERE Caa.Person_Id  IS NOT NULL 
   AND publication.id IN 
       (SELECT DISTINCT pure.publication_project_assoc.publication_id
... 

答案 1 :(得分:0)

这就是你要找的东西:

SELECT FirstQuery.*, SecondQuery.*
FROM
    (
        SELECT publication_id AS Pure_Publication_Id, caa.person_id, 
            caa.name_first_name AS Primary_Author_First_Name,
            caa.name_last_name AS Primary_Author_Last_Name
        FROM pure.classified_author_assoc caa
            LEFT OUTER JOIN Pure.Publication
                ON Caa.Publication_Id = Publication.Id
        WHERE Caa.Person_Id  IS NOT NULL
            AND EXISTS
            (
                SELECT 1 
                FROM Pure.project
                JOIN Pure.Publication_project_assoc
                    ON project.id = Pure.Publication_project_assoc.project_id
                WHERE pure.publication_project_assoc.publication_id = publication.id
                    AND pure.project.source_id IN ('XEP378', 'XES049', 'YAH001')
        )
        GROUP BY publication_id, caa.person_id, caa.name_first_name, caa.name_last_name
    ) AS FirstQuery
    FULL OUTER JOIN
    (
        SELECT publication.id AS Pure_Publication_Id, 
            COUNT (person_id) AS "NUMBER_OF_AUTHORS", 
            CASE WHEN COUNT (person_id) > 1 THEN 'Yes' 
                else 'No' END AS Additional_Authors
        FROM pure.classified_author_assoc caa
            LEFT OUTER JOIN Pure.Publication
                ON Caa.Publication_Id = Publication.Id
        WHERE Caa.Person_Id  IS NOT NULL
            AND EXISTS
            (
                SELECT 1 
                FROM Pure.project
                    JOIN Pure.Publication_project_assoc
                        ON project.id = Pure.Publication_project_assoc.project_id
                WHERE pure.publication_project_assoc.publication_id = publication.id
                    AND pure.project.source_id IN ('XEP378', 'XES049', 'YAH001')
            )
       GROUP BY publication.id
    ) AS SecondQuery
        ON FirstQuery.Pure_Publication_Id = SecondQuery.Pure_Publication_Id

可能有一种方法可以做得更整洁,但这就是你应该如何执行FULL OUTER JOIN。它使用嵌套查询。现在,请记住,如果FULL OUTER JOIN没有任何计数,FirstQuery将返回NULL结果。所以,我建议将其更改为LEFT JOIN。这将确保FirstQuery中存在值,但如果SecondQuery

中没有匹配值,则无关心

优化点/注释的更新

  • 通过添加publication.id IN,您可以取消LEFT JOIN。如果您希望它真正属于LEFT JOIN,则必须将此过滤条件放入LEFT JOIN的{​​{1}}声明中
  • 将您的ON更改为IN以减少混乱并获得相同的结果