两次加入同一张桌子并选择一对

时间:2019-05-01 03:06:05

标签: sql oracle

我有2张桌子:

staff (enum,ename,title)
101,Zhivago,Doctor
102,Welby,Doctor
103,Jekyl,Doctor
104,Caligari,Doctor
105,Nightingale,Nurse
106,Ratchet,Nurse

expertise (enum,code)
101,4001
101,4002
101,4003
101,4004
101,4005
101,4006
102,4002
102,4003
102,4006
103,4001
103,4006
103,4004
104,4004
104,4006
105,4002
105,4003
105,4004
105,4006
106,4001
106,4002
106,4003
106,4004
106,4005
106,4006

我如何获得一对医生和护士(枚举,名字,头衔,枚举, ename,title)至少具有一种专业知识。

还有一对医生和护士(枚举,名字,头衔,枚举, 完全相同的专业知识。

2 个答案:

答案 0 :(得分:0)

您可以将listagg()窗口分析功能与self-join一起用于专业知识表,而仅通过使用having子句保留配对对

select listagg(e.enum||','||s.ename||','||s.title,';') 
        within group (order by e.enum) as "Grouped Results"
  from staff s
  join expertise e 
    on e.enum = s.enum
  join expertise e2 
    on e2.enum = s.enum and e2.code = e.code
 group by e.code
 having count(1)>1

Demo

答案 1 :(得分:0)

我相信此SQL将获得预期的结果:

第1部分:我如何获得至少共享一种专业知识的成对的医生和护士(枚举,名字,标题;枚举,名字,标题)。

说明:选择具有任何专业知识的与护士匹配的所有医生;筛选出不同的结果。

SELECT DISTINCT
    s1.enum as doctor_enum,
    s1.ename as doctor_ename,
    s1.title as doctor_title,
    s2.enum as nurse_enum,
    s2.ename as nurse_ename,
    s2.title as nurse_title
  from staff as s1
  inner join expertise as e1 on e1.enum = s1.enum
  inner join expertise as e2 on e2.code = e1.code
  inner join staff as s2 on s2.enum = e2.enum
  where s1.title = 'Doctor'
    and s2.title = 'Nurse';

第1部分结果:

doctor_enum doctor_ename    doctor_title    nurse_enum  nurse_ename nurse_title
101 Zhivago Doctor  105 Nightingale Nurse
102 Welby   Doctor  105 Nightingale Nurse
103 Jekyl   Doctor  105 Nightingale Nurse
101 Zhivago Doctor  106 Ratchet Nurse
103 Jekyl   Doctor  106 Ratchet Nurse
102 Welby   Doctor  106 Ratchet Nurse
104 Caligari    Doctor  105 Nightingale Nurse
104 Caligari    Doctor  106 Ratchet Nurse

第2部分:还具有完全相同的专业知识的医生和护士对(枚举,名字,标题;枚举,名字,标题)。

说明:选择与上述相同,但是请检查是否有任何医生专业知识与护士不符,反之亦然。

SELECT DISTINCT
    s1.enum as doctor_enum,
    s1.ename as doctor_ename,
    s1.title as doctor_title,
    s2.enum as nurse_enum,
    s2.ename as nurse_ename,
    s2.title as nurse_title
  from staff as s1
  inner join expertise as e1 on e1.enum = s1.enum
  inner join expertise as e2 on e2.code = e1.code
  inner join staff as s2 on s2.enum = e2.enum
  where s1.title = 'Doctor'
    and s2.title = 'Nurse'
    and not exists (
          SELECT *
            FROM expertise e1
            WHERE e1.enum = s1.enum
              AND e1.code NOT IN (
                    SELECT code FROM expertise e2 WHERE e2.enum = s2.enum
              )
     )
    and not exists (
          SELECT *
            FROM expertise e2
            WHERE e2.enum = s2.enum
              AND e2.code NOT IN (
                    SELECT code FROM expertise e1 WHERE e1.enum = s1.enum
              )
     );

第2部分结果:

doctor_enum doctor_ename    doctor_title    nurse_enum  nurse_ename nurse_title
101 Zhivago Doctor  106 Ratchet Nurse

以下是任何使用此答案的人的架构脚本:

CREATE TABLE staff (
    `enum` int,
    `ename` nvarchar(50),
    `title` nvarchar(50)
);

 INSERT INTO staff VALUES
   (101,'Zhivago','Doctor'), 
   (102,'Welby','Doctor'), 
   (103,'Jekyl','Doctor'), 
   (104,'Caligari','Doctor'), 
   (105,'Nightingale','Nurse'), 
   (106,'Ratchet','Nurse');

CREATE TABLE expertise (
   `enum` int,
   `code` int
);

INSERT INTO expertise VALUES
  (101,4001),
  (101,4002),
  (101,4003),
  (101,4004),
  (101,4005),
  (101,4006),
  (102,4002),
  (102,4003),
  (102,4006),
  (103,4001),
  (103,4006),
  (103,4004),
  (104,4004),
  (104,4006),
  (105,4002),
  (105,4003),
  (105,4004),
  (105,4006),
  (106,4001),
  (106,4002),
  (106,4003),
  (106,4004),
  (106,4005),
  (106,4006);

希望这会有所帮助。