表中不存在且不重复的sql数据

时间:2018-10-09 13:07:03

标签: sql rdbms-agnostic

有点棘手,请关注我的要求,我有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 ,因此我必须排除它们,因此我应该具有ID 3, 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 个答案:

答案 0 :(得分: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
                              )

答案 1 :(得分: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
)

答案 2 :(得分:1)

只需添加使用CTE的方法,您就可以首先确定唯一的childidsubid对,然后将该表与主表连接起来:

DB Fiddle

模式(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         |

答案 3 :(得分: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,前提是假设第一个表中的行是唯一的。没有这种假设,窗口函数将是最佳解决方案,而且无论如何可能都是最佳解决方案。