三-table 加入 NO EXISTS

Three-table join with NO EXISTS

我有三个 table,想在 SQL 中回答以下问题:

“谁只有证书没有分数?”

例如,在下面的设置中,查询只会 return “John”。 Joana 拥有 SCORE table (id 57) 中的“AWS 认证”。 Marry 拥有不在 SCORE table 中的“ITIL V3 认证”,但她也有“Professional Python Dev”,在你的 SCORE table.

PERSON
| PERSON_ID | PERSON_NAME |
| --------  | -------------- |
| 12    | John            |
| 23   | Mary            |
| 24   | Joana            |


**CERTIFICATION**
|CERTIFICATION_ID| CERTIFICATION_NAME | PERSON_ID|
| -------- |----------- | -------------- |
| 53 | Java Certification    |    12       |
| 54 | ITIL V3 Certification    |    23       |
| 55 | Professional Python Dev            | 23|
| 56 |GCP Certification            |23   | 
| 57 |AWS Certification            |24   | 

SCORES

|SCORE_ID| CERFITICATION_ID | SCORE_DETAILS |
| -------- |----------- | -------------- |
| 70 |55   | 80%            |
| 71 |56   | 90%            |
| 72 |57   | 95%           |

我试图在 SQL 中实现它,而不必遍历记录并且不使用存储过程。

SQL 用于创建这些 table 并添加数据以备不时之需:

create table person(
person_id integer,
person_name varchar(16)
);

create table certification(
CERTIFICATION_ID int,
  CERTIFICATION_NAME varchar(16),
  person_id int
);

create table scores(
  SCORE_ID int,
  CERTIFICATION_ID int,
 SCORE_DETAILS varchar(16));


insert into person(person_id, person_name) values(12, 'John');
insert into person(person_id, person_name) values(23, 'Mary');
insert into person(person_id, person_name) values(24, 'Joana');


insert into certification(CERTIFICATION_ID,CERTIFICATION_NAME,person_id) values(53,'A', 12);
insert into certification(CERTIFICATION_ID,CERTIFICATION_NAME,person_id) values(54,'B',23);
insert into certification(CERTIFICATION_ID,CERTIFICATION_NAME,person_id) values(55,'C', 23);
insert into certification(CERTIFICATION_ID,CERTIFICATION_NAME,person_id) values(56,'D', 23);
insert into certification(CERTIFICATION_ID,CERTIFICATION_NAME,person_id) values(57,'E', 24);

insert into scores (SCORE_ID,CERTIFICATION_ID, SCORE_DETAILS) values (70,55,'e');
insert into scores (SCORE_ID,CERTIFICATION_ID, SCORE_DETAILS) values (71,56,'f');
insert into scores (SCORE_ID,CERTIFICATION_ID, SCORE_DETAILS) values (72,57,'g');

我们可以像下面这样使用not

select p.* from person p
 where p.person_id not in (
select c.person_id from 
certification c join scores s on c.CERTIFICATION_ID=s.CERTIFICATION_ID
)

demo link

您可以使用以下查询

select *
  from person p
 where not exists (select 1
                 from certification c
                 join scores s on s.certification_id = c.certification_id
                where p.person_id = c.person_id
              )