创建 SQL 查询以将多个相关行组合在一起

Creating a SQL query to combine multiple related rows together

不知道你能不能帮帮我?我是 SQL 的新手,我真的很难解决这个问题。我环顾四周,但作为新手,我很快就搞糊涂了!

我为一组公司客户继承了 table 个不同的地址。 table 在 Oracle 12c 服务器上,我正在使用 SQL Developer。

我想将此信息附加到另一个查询的末尾,这样人们就可以更轻松地在最终报告中查看单个客户的所有相关信息。

table 的布局如下:

| 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。因此,我不想每个 ADDRESS_TYPE 每个 CUST_ID 有一行,我想每个 CUST_ID 有一行,每个 ADDRESS_TYPE 的寻址信息作为额外的列。我会使用 CUST_ID 将结果加入另一个查询。

我不知道我是否应该尝试使用多个连接或者我是否可以进行某种子查询?

非常感谢您的宝贵时间和帮助,非常感谢!

您可以使用条件聚合:

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;

您也可以使用联接

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'

或者您可以使用 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 : 我很好奇时间。我想一定是像聚合方法