Oracle SELECT QUERY用于两个表之间的一对多关系

时间:2016-07-21 20:15:43

标签: sql oracle

我不是SQL专家,但我正在学习。我试图弄清楚如何在一对多关系中编写两个表的查询。

Table1有人信息: (PersonId, FirstName, MiddleName, LastName)table2(PersonId, Phone, PhoneType)

到目前为止,这是我的查询

select Table1.PERSON_ID, 
Table1.FIRST_NAME, 
Table1.MIDDLE_NAME, 
Table1.LAST_NAME, 
Table2.PHONE_NUMBER
from Table1
inner join Table2
on Table2.PERSON_ID = Table1.PERSON_ID
where Table2.PHONE_TYPE in ('BUSINESS','PERSONAL','HOME')

这是表格

Table1
PERSON_ID     FIRST_NAME     MIDDLE_NAME     LAST_NAME
1             John           Carter          Jones

Table2
PERSON_ID     PHONE_NUMBER   PHONE_TYPE
1             111-111-1111   HOME
1             111-111-1112   PERSONAL
1             111-111-1113   BUSINESS

从我的查询中得到

1     John Carter Jones 111-111-1111
1     John Carter Jones 111-111-1112
1     John Carter Jones 111-111-1113

我想实现以下结果

1     John Carter Jones 111-111-1111 111-111-1112 111-111-1113

我尝试使用LISTAGG来合并电话号码。它在一列中为我提供了所有3个电话号码。如何将LISTAGG的输出作为3个单独的列。

TOAD上的输出如下所示

1 John M. Doe" 2022222222,2023333333"

这是我的查询

select 
PERSON.PERSON_ID, 
PERSON.FIRST_NAME,
PERSON.MIDDLE_NAME,
PERSON.LAST_NAME,
LISTAGG(PHONE_NUMBER, ',') WITHIN GROUP (ORDER BY PHONENUMBERS.PHONE_NUMBER) 
FROM Table1 PERSON
INNER JOIN (SELECT PERSON_ID, PHONE_NUMBER, UPDATED_DT, PHONE_TP_SHORT_DESC FROM Table2) PHONENUMBERS
ON PERSON.PERSON_ID = PHONENUMBERS.PERSON_ID AND PHONENUMBERS.PHONE_TP_SHORT_DESC IN ('HOME','BUSINESS','CELL')
GROUP BY   
PERSON.PERSON_ID, 
PERSON.FIRST_NAME,
PERSON.MIDDLE_NAME,
PERSON.LAST_NAME

2 个答案:

答案 0 :(得分:1)

一种方法使用条件聚合:

select t1.PERSON_ID, t1.FIRST_NAME, t1.MIDDLE_NAME, t1.LAST_NAME, 
       max(case when t2.phone_type = 'BUSINESS' then t2.PHONE_NUMBER end) as business,
       max(case when t2.phone_type = 'PERSONAL' then t2.PHONE_NUMBER end) as personal,
       max(case when t2.phone_type = 'HOME' then t2.PHONE_NUMBER end) as home
from Table1 t1 inner join
     Table2 t2
     on t2.PERSON_ID = t1.PERSON_ID
where t2.PHONE_TYPE in ('BUSINESS', 'PERSONAL', 'HOME') 
group by t1.PERSON_ID, t1.FIRST_NAME, t1.MIDDLE_NAME, t1.LAST_NAME;

答案 1 :(得分:0)

从Oracle 11g开始,此选项可用: WITH Table1 AS ( SELECT 1 PERSON_ID, 'John' FIRST_NAME, 'Carter' MIDDLE_NAME, 'Jones' LAST_NAME FROM DUAL ), Table2 AS ( SELECT 1 PERSON_ID, '111-111-1111' PHONE_NUMBER, 'HOME' PHONE_TYPE FROM DUAL UNION ALL SELECT 1 PERSON_ID, '111-111-1112' PHONE_NUMBER, 'PERSONAL' PHONE_TYPE FROM DUAL UNION ALL SELECT 1 PERSON_ID, '111-111-1113' PHONE_NUMBER, 'BUSINESS' PHONE_TYPE FROM DUAL ) SELECT * FROM ( SELECT T1.PERSON_ID, T1.FIRST_NAME, T1.MIDDLE_NAME, T1.LAST_NAME, T2.PHONE_TYPE, t2.PHONE_NUMBER FROM Table1 T1 INNER JOIN Table2 t2 ON t2.PERSON_ID = T1.PERSON_ID WHERE t2.PHONE_TYPE IN ('HOME', 'PERSONAL', 'BUSINESS') ) PIVOT ( MAX(PHONE_NUMBER) AS Tel FOR (PHONE_TYPE) IN ('HOME' AS HOME, 'PERSONAL' AS PERSONAL, 'BUSINESS' AS BUSINESS) )