2017-07-28 172 views
1

不知您是否可以帮助我?我是新来的SQL,我真的很苦恼这个查询。我环顾四周,但是很新,我很快就感到困惑!创建SQL查询将多个相关行组合在一起

我为一组企业客户继承了不同地址的表。该表位于Oracle 12c服务器上,我正在使用SQL Developer。

我想将此信息附加到另一个查询的末尾,以便人们在结束报告中查看单个客户的所有相关信息更容易一些。

该表是布局像这样:

| CUST_ID | ADDRESS_TYPE | CONTACT_NAME | ADDRESS | CITY | ... | 
------------------------------------------------------------------ 
|  1000|   SITE |  A SMITH | A ROAD | A TOWN | 
|  1000|  BUILDER |  B JONES | B ROAD | B TOWN | 
|  1000| ARCHITECT |  A BROWN | C ROAD | A CITY | 
|  1001|   SITE |  B SMITH | A LANE | C TOWN | 
|  1001| ARCHITECT |  D BROWN | D ROAD | B CITY | 
|  1002|   SITE |  E SMITH | B LANE | D TOWN | 
|  1002| ARCHITECT |  C JONES | B ROAD | A CITY | 
|  1002|  BUILDER |  F SMITH | C LANE | B TOWN | 

我想创造的是:

| CUST_ID | SITE_NAME | SITE_ADDRESS | SITE_TOWN | BUILDER_NAME | BUILDER_ADDRESS | BUILDER_TOWN | ... | 
| 1000 | A SMITH |  A ROAD | A TOWN |  B JONES |   B ROAD |  B TOWN | ... | 
| 1001 | B SMITH |  A LANE | A TOWN |   NULL |   NULL |   NULL | ... | 
| 1002 | E SMITH |  B LANE | D TOWN |  F SMITH |   C LANE |  B TOWN | ... | 

有3 ADDRESS_TYPE,我感兴趣的是:SITEBUILDERARCHITECT。因此,我不希望每CUST_IDADDRESS_TYPE有一行,我想每CUST_ID得到一行,每个ADDRESS_TYPE的寻址信息作为额外的列。我将使用CUST_ID将结果加入另一个查询。

我不知道我是否应该尝试多个连接或是否可以做某种子查询?

非常感谢您的时间和帮助,我真的很感激它!

回答

1

您还可以使用加入

SELECT 
    BASE.CUST_ID, 
    SITE.CONTACT_NAME AS SITE_NAME, 
    SITE.ADDRESS AS SITE_ADDRESS, 
    SITE.CITY AS SITE_CITY, 
    BUILDER.CONTACT_NAME AS BUILDER_NAME, 
    BUILDER.ADDRESS AS BUILDER_ADDRESS, 
    BUILDER.CITY AS BUILDER_CITY, 
    ARCHITECT.CONTACT_NAME AS ARCHITECT_NAME, 
    ARCHITECT.ADDRESS AS ARCHITECT_ADDRESS, 
    ARCHITECT.CITY AS ARCHITECT_CITY 
FROM (SELECT DISTINCT CUST_ID FROM TABLE_YOU_DID_NOT_NAME) BASE 
LEFT JOIN TABLE_YOU_DID_NOT_NAME SITE ON BASE.CUST_ID = SITE.CUST_ID AND SITE.ADDRESS_TYPE = 'SITE' 
LEFT JOIN TABLE_YOU_DID_NOT_NAME BUILDER ON BASE.CUST_ID = BUILDER.CUST_ID AND BUILDER.ADDRESS_TYPE = 'BUILDER' 
LEFT JOIN TABLE_YOU_DID_NOT_NAME ARCHITECT ON BASE.CUST_ID = ARCHITECT.CUST_ID AND ARCHITECT.ADDRESS_TYPE = 'ARCHITECT' 
+0

感谢Hogan,我不确定在重复引用同一个表时连接是否合适。我认为它可能真的效率低下,但现在我知道只是放弃它!再次感谢您的帮助 – Nikkunaku

+0

@Nikkunaku - 根据表格的大小和定义的索引,这样可以比使用聚合更快 – Hogan

+0

我最终试用了两种方法,并且您的联合版本在1.74秒内获得了380k结果而对于条件聚合方法只有不到10秒。因为它更容易看到发生了什么并且更快,所以将其更改为答案。再次感谢您的帮助:D – Nikkunaku

1

可以使用条件汇总:

select cust_id, 
     max(case when address_type = 'Site' then Contact_Name end) as site_name, 
     max(case when address_type = 'Site' then Town end) as site_town, 
     max(case when address_type = 'Site' then Address end) as site_address, 
     max(case when address_type = 'Builder' then Contact_Name end) as builder_name, 
     max(case when address_type = 'Builder' then Town end) as builder_town, 
     max(case when address_type = 'Builder' then Address end) as builder_address, 
     . . . 
from t 
group by cust_id; 
+0

Oooh这对我来说是全新的,谢谢!它的工作,它真的很快!感谢您的帮助Gordon,我将把条件汇总添加到我的列表中,以便详细了解:D – Nikkunaku

0

或者你可以使用PIVOT(只是要详尽的不同的解决方案)

Link to SQLFiddle

select * from addresses 
pivot ( 
    MAX(CONTACT_NAME) CONTACT_NAME, 
    MAX(ADDRESS) ADDRESS, 
    MAX(CITY) CITY 
    FOR ADDRESS_TYPE IN ('SITE','BUILDER','ARCHITECT')); 

@OP:我会好奇时间的。我想必须像聚合方法