组合2个select语句

时间:2015-11-19 07:41:49

标签: sql oracle oracle11g

我有2个select语句,它们有一个共同的列POL.SP_NUM,我希望将它组合在一起。我是SQL的新手,并没有丝毫的线索如何去做同样的事情。

查询1:

select  POL.SP_NUM POL#
,       POL.ASSET_NUM COV#
,       count(distinct(POLX.ATTRIB_06)) COUNT_ADDENDA
,       count(distinct(POLX.ATTRIB_07)) COUNT_CERT
,       sum(POL.QTY) SI
from    S_ASSET POL
,       S_ASSET_X POLX 
Where   POL.ROW_ID  =   POLX.ROW_ID
and     POL.SP_NUM  in  ('000','111','222')
group by
        POL.SP_NUM
,       POL.ASSET_NUM

查询1输出:

POL#    COV#    COUNT_ADDENDA   COUNT_CERT      SI
000     856     2               0               1000
111     123     0               0               500
222     567     0               1               2000

查询2:

select POL#, sum(DOCI) 
from    (
            select  POL.SP_NUM POL#, sum(Q.AMT + POL.AMT) DOCI 
            from    S_ASSET POL
            ,       S_QUOTE_ITEM Q 
            where   POL.X_QUOTE_ID  =   Q.ROW_ID 
            and     POL.SP_NUM      in  ('000','111','222')
            group by POL.SP_NUM

            UNION ALL

            select  POL.SP_NUM POL#, sum(QXM.AMT) DOCI 
            from    S_ASSET POL
            ,       S_QUOTE_ITEM Q
            ,       S_QUOTE_ITEM_XM QXM 
            where   POL.X_QUOTE_ID  =   Q.ROW_ID 
            and     Q.ROW_ID        =   QXM.PAR_ROW_ID 
            and     POL.SP_NUM      in  ('000','111','222')
            group by POL.SP_NUM
        )
group by POL#

查询2输出:

POL#    sum(DOCI)
000     90
111     0
222     10

期望的输出:

POL#    COV#    COUNT_ADDENDA   COUNT_CERT      SI          sum(DOCI)
000     856     2               0               1000        90
111     123     0               0               500         0
222     567     0               1               2000        10

如果有更好的方法来编码吗?欢迎提出建议。

2 个答案:

答案 0 :(得分:1)

这个问题没有答案,但答案是解释评论中所提出的连接类型的请求。

INNER JOIN(或简称:JOIN)

 select * from t1 join t2 on t1.colx = t2.coly

仅为您提供比赛。这是最常见的连接。如果ON子句中的列在表中具有相同的名称,则可以使用USING子句替换ON子句。有时可以快速编写查询,但我一般不建议使用。

LEFT OUTER JOIN(或简称:LEFT JOIN)

 select * from t1 left join t2 on t1.colx = t2.coly

给你所有t1记录,无论他们是否在t2中有数学。所以当t1记录匹配或更多时,你加入这些就像内连接一样,但是当t1记录在t2中没有匹配时,你得到t1记录和一个空的t2记录(所有列都是NULL,甚至是你在ON子句中使用的列,在上面的例子中是t2.coly)。换句话说:你获得了内连接所得到的所有记录以及t2中没有匹配的所有t1记录。

你也可以使用RIGHT JOIN,这样你就可以在没有t1匹配时保留t2记录:

 select * from t1 right join t2 on t1.colx = t2.coly

但是这被许多人认为不太可读,所以最好不要使用右外连接,而只需交换表:

 select * from t2 left join t1 on t1.colx = t2.coly

FULL OUTER JOIN(或简称:FULL JOIN)

 select * from t1 full outer join t2 on t1.colx = t2.coly

这将为您提供来自t1和t2的所有记录,无论它们是否与另一个表中的匹配。再说一遍:你获得了内连接所得到的所有记录加上没有t2匹配的所有t1加上没有t1匹配的所有t2。

当有多个完整的外连接时,USING子句可以派上用场:

 select product, sum(p1.amount), sum(p2.amount), sum(p3.amount)
 from p1 
 full outer join p2 using (product)
 full outer join p3 using (product);

CROSS JOIN

交叉连接加入没有任何条件的表,以便将其记录的每个已存在的记录的每个组合在一起。这用于获取所有组合,通常后跟左外连接:

 select products.product_id, regions.region_id, count(*) 
 from products
 cross join regions
 left join sales on sales.product_id = products.product_id 
                 and sales.region_id = regions.region_id
 group by products.product_id, regions.region_id
 order by products.product_id, regions.region_id;

这为您提供了产品和地区的所有可能组合,并计算其中的销售额。因此,即使没有销售任何产品/区域组合(即表销售中没有条目),您也会获得结果记录。

NATURAL JOIN

查看常用列名以神奇地连接表。我的简单建议:永远不要使用这种连接类型。

ANTI JOIN

这实际上不是连接类型,而是连接的用法,即外连接。在这里,您希望从表中获取所有记录,但匹配。您可以通过外连接表然后删除where子句中的匹配来实现此目的。

 select t1.* 
 from t1 
 left join t2 on t1.colx = t2.coly 
 where t2.coly is null;

这看起来很奇怪,因为我们有EXISTS(和IN)来检查是否存在:

 select * 
 from t1 
 where not exists (select * from t2 where t2.coly = t1.colx);

那么为什么会混淆事物并使用反连接模式呢?这是弱DBMS上使用的技巧。编写DBMS时,连接是最重要的事情,DBMS的开发人员将全力以赴加快速度。他们可能会先忽略EXISTS和IN,然后才会关注他们的表现。因此,它可能有助于使用连接技术(反连接)。我的建议:仅在使用直接查询遇到性能问题时才使用反连接模式。到目前为止,我已经二十多年没有使用反连接了。 (尽管有这个选项很好。而且了解它们很好,以免在遇到这样的查询时感到困惑: - )

答案 1 :(得分:0)

您可以加入查询:

select *
from (your query 1 here) query1
join (your query 2 here) query2 on query2.pol# = query1.pol#;

与WITH子句相同:

with query1 as (your query 1 here),
     query2 as (your query 2 here)
select *
from query1
join query2 on query2.pol# = query1.pol#;