优化union sql查询

时间:2013-05-23 00:22:32

标签: sql plsql oracle9i plsqldeveloper oracle-sqldeveloper

我正在3张桌子之间做一个UNION。为了使您了解,一个表被视为主表,另外两个表被视为子表。对于每种情况,2个子表始终具有相同数量的记录。所以我想在这三个表之间建立一个联合,在这个联合中我想重复主表中提取的列中的信息并列出2个子表中的信息,其中子表1中的每一行对应于该行在子表2中。由于专业原因,我无法输入实际代码,所以这里有一个与我的实例相对应的简单示例。 考虑一个名为Author(Author_ID,Author_FirstName,Author_LastName)的表。这张表将是我们的主要表格。然后考虑我们有一个名为Adresses(Adress_ID,Street_Coord,Author_ID)的表,这将是我们的子表1.然后考虑名为Cities(City_ID,City_Name,Author_ID)的表。我们的作者X在2个城市有2个地址。当我执行我的查询时,我得到的结果R1完全合乎逻辑,但我想修改我的查询以获得结果R2。你能帮我改变一下我的查询来得到结果R2吗?

SQL查询:

SELECT "Author"."Author_ID", "Author"."Author_FirstName", "Author.Author_LastName",
       TO_CHAR(NULL) AS "Street_Coord", TO_CHAR(NULL) AS "City_Name"
FROM "Author"
WHERE "Author"."Author_ID"='X'

UNION

SELECT TO_NUMBER(NULL) AS "Author_ID", TO_CHAR(NULL) AS "Author_FirstName", TO_CHAR(NULL) AS "Author_LastName", 
       "Adresses"."Street_Coord", TO_CHAR(NULL) AS "City_Name" 
FROM "Adresses"
WHERE "Adresses"."Author_ID"='X'

UNION

SELECT TO_NUMBER(NULL) AS "Author_ID", TO_CHAR(NULL) AS "Author_FirstName", TO_CHAR(NULL) AS "Author_LastName", 
       TO_CHAR(NULL) AS "Street_Coord", "Cities"."City_Name"
FROM "Cities"
WHERE "Cities"."Author_ID"='X'

结果R1:

ID_AUTHOR | AUTHOR_FirstName | AUTHOR_LastName | Street_Coord   | City_Name       |
----------------------------------------------------------------------------------
X         |James             | Conor           | NULL           | NULL            |
----------------------------------------------------------------------------------
X         |NULL              | NULL            | 1245 rich st   | NULL            |
----------------------------------------------------------------------------------
X         |NULL              | NULL            | 154 music st   | NULL            |
----------------------------------------------------------------------------------
X         |NULL              | NULL            | NULL           | Madrid          |
----------------------------------------------------------------------------------
X         |NULL              | NULL            | NULL           | Barcelona       |
----------------------------------------------------------------------------------

结果R2:我希望你能帮助我得到这个结果:

ID_AUTHOR | AUTHOR_FirstName | AUTHOR_LastName | Street_Coord   | City_Name       |
----------------------------------------------------------------------------------
X         |James             | Conor           | 1245 rich st   | Madrid          |
----------------------------------------------------------------------------------
X         |James             | Conor           | 154 music st   | Barcelona       |
----------------------------------------------------------------------------------

非常感谢, Walloud

2 个答案:

答案 0 :(得分:0)

首先想到的是你真的想要一起加入这些桌子。类似的东西:

SELECT "Author"."Author_ID", "Author"."Author_FirstName", "Author.Author_LastName",
       "Adresses"."Street_Coord", "Cities"."City_Name"
FROM "Author" join
     "Adresses"
     on Author.Author_id = Adresses.Author_id join
     Cities
     on Author.Author_id = Cities.Author_id 
WHERE "Author"."Author_ID"='X';

但是,这将返回值的笛卡尔积,即4行而不是2行。似乎目的是“对齐”不同的表格。在这种情况下,此查询接近您想要的内容:

SELECT "Author"."Author_ID", "Author"."Author_FirstName", "Author.Author_LastName",
       "Adresses"."Street_Coord", "Cities"."City_Name"
FROM "Author" join
     (select a.*, rownum as seqnum from "Adresses" a
     ) Adresses
     on Author.Author_id = Adresses.Author_id join
     (select c.*, rownum as seqnum from Cities c
     ) Cities
     on Author.Author_id = Cities.Author_id and addresses.seqnum = cities.seqnum
WHERE "Author"."Author_ID"='X';

这种方法的主要问题是SQL表本质上是无序的。您需要一些列来订购这些列,以确保查询能够正常工作。例如,如果表中有自动递增ID,则每个子查询可以order by id

答案 1 :(得分:0)

你不想做UNION,你想做一个JOIN:

SELECT "Author"."Author_ID", "Author"."Author_FirstName", "Author.Author_LastName", "Adresses"."Street_Coord", "Cities"."City_Name"
 FROM "Author"
 INNER JOIN "Adresses" ON "Author"."Author_ID"="Adresses"."Author_ID"
 INNER JOIN "Cities" ON "Author"."Author_ID"="Cities"."Author_ID"
 WHERE "Author"."Author_ID"='X'

没有测试它,它可能包含一些拼写错误......

此外,您需要在“地址”和“城市”之间添加一个额外的连接列,以匹配“1245 rich st”与“Madrid”和“154 music st”和“Barcelona”。像“City_ID”之类的东西。然后在INNER JOIN ... ON子句中添加它:

INNER JOIN "Cities" ON "Adresses"."City_ID"="Cities"."City_ID" AND "Author"."Author_ID"="Cities"."Author_ID"