1

这有点棘手,请关注我的要求,我有 2 个表,我想从第一个表中获取第二个表中不存在的数据,并且第一列中的数据对于子 ID 和子 ID 不重复。

示例:我有这张桌子

tab1 

id   subid     childid
1     11       77
2     22       55
3     33       66
4     11       77
7     22       55
8     33       60
9     99       98
10    33       60
11    97       98

tab2

id
1
4
7
10

我想要的第一件事是tab1中的id在tab2中不存在, 2,3,8,9,11但是其中一些id有重复的subid和chilid所以我必须排除它们因此我应该有id3, 9, 11

我试过这个查询,但它也返回了 3 ,9 ,11, 8 ,我不想要 8 如何修复查询?

select *
  from tab1 a
 where not exists (select 1 from tab2 b where a.id = b.id)
 and a.sub_id in (select c.sub_id
                                from tab1 c
                                group by c.sub_id,c.evt_id
                                having count(1) = 1)
4

4 回答 4

1

我认为下面的查询会起作用

select a.*
  from tab1 a
 where not exists (select 1 from tab2 b where a.id = b.id)
 and  not exists (select 1  from tab1 c 
                                 where c.sub_id = a.sub_id 
                                 and c.childid = a.childid
                                 group by c.sub_id,childid
                                 having count(*)> = 2
                              )
于 2018-10-09T13:10:55.367 回答
1

对于多个数据库供应商,我认为最简单的解决方案是几个not exists查询:

select *
from tab1 a
where not exists (
    select 1 
    from tab2 b 
    where a.id = b.id
)
and not exists (
    select 1 
    from tab1 c 
    where c.sub_id = a.sub_id 
    and c.evt_id = a.evt_id 
    and c.id <> a.id
)
于 2018-10-09T13:13:33.700 回答
1

只是要使用 CTE 添加一种方法,您可以首先确定唯一的childid,subid对,然后将该表与您的主表连接:

DB小提琴

架构(PostgreSQL v9.6)

create table tab1 (
  id integer primary key unique not null
, subid integer not null
, childid integer not null
  );
insert into tab1 (id,subid,childid) values (1, 11, 77);
insert into tab1 (id,subid,childid) values (2, 22, 55);
insert into tab1 (id,subid,childid) values (3, 33, 66);
insert into tab1 (id,subid,childid) values (4, 11, 77);
insert into tab1 (id,subid,childid) values (7, 22, 55);
insert into tab1 (id,subid,childid) values (8, 33, 60);
insert into tab1 (id,subid,childid) values (9, 99, 98);
insert into tab1 (id,subid,childid) values (10, 33,60);
insert into tab1 (id,subid,childid) values (11,    97       ,98);

create table tab2 (
      id integer primary key unique not null
  );

insert into tab2 (id) values (1);
insert into tab2 (id) values (4);
insert into tab2 (id) values (7);
insert into tab2 (id) values (10);

查询 #1

with tab1_unique as (
    select subid, childid, count(*) as duplicate
      from tab1
     group by subid, childid
    having count(*) = 1
)
select *
  from tab1 a
  join tab1_unique u on a.subid = u.subid and a.childid = u.childid
 where not exists (select 1 from tab2 b where a.id = b.id);

| id  | subid | childid | subid | childid | duplicate |
| --- | ----- | ------- | ----- | ------- | --------- |
| 11  | 97    | 98      | 97    | 98      | 1         |
| 9   | 99    | 98      | 99    | 98      | 1         |
| 3   | 33    | 66      | 33    | 66      | 1         |
于 2018-10-09T13:22:14.843 回答
0

not exists应该这样做:

select t1.*
from (select t1.*, count(*) over (partition by subid, childid) as cnt
      from tab1 t1
     ) t1
where not exists (select 1 from tab2 t2 where t2.id = t1.id) and
      cnt = 1;

not exists您也可以使用subid/childid 并假设行在第一个表中是唯一的。如果没有这个假设,窗口函数是最好的解决方案——而且可能是最好的解决方案。

于 2018-10-09T13:11:24.527 回答