查找查询中缺少的记录

时间:2019-08-05 16:10:43

标签: sql postgresql

我有以下数据库表

tbl_setup

id
peer
gw

我那里有以下记录

1 | HA | GW1
2 | HA | GW2
3 | HA | GW3
4 | AA | GW1
5 | AB | GW2
6 | AB | GW3
7 | AB | GW4
8 | EE | GW3

试图找出一个查询来找出哪些GW丢失了数据,所以试图找出一个查询给我以下结果,这就是GW的丢失

HA | GW4
AA | GW2
AA | GW3
AA | GW4
AB | GW1
EE | GW1
EE | GW2
EE | GW4

应该只有4 GW的GW1-GW4,永远不会超过此数量

2 个答案:

答案 0 :(得分:1)

使用两列的cross join值中的distinct,然后选择not exists

select *
from (select distinct gw from tablename) g 
cross join (select distinct peer from tablename) p 
where not exists (
  select 1 from tablename
  where gw = g.gw and peer = p.peer
)
order by gw, peer

请参见demo
或者:

select g.gw, p.peer
from (select distinct gw from tablename) g 
cross join (select distinct peer from tablename) p 
left join tablename t
on t.gw = g.gw and t.peer = p.peer
where t.id is null
order by g.gw, p.peer

请参见demo
结果:

| gw  | peer |
| --- | ---- |
| AA  | GW2  |
| AA  | GW3  |
| AA  | GW4  |
| AB  | GW1  |
| EE  | GW1  |
| EE  | GW2  |
| EE  | GW4  |
| HA  | GW4  |

答案 1 :(得分:0)

想法是执行cross join来获取所有行,然后过滤掉存在的行。有几种方法可以进行过滤。我通常使用left join,尽管not exists,不在, and中,但是`都是合理的选择。

如果所有对等点和gws都在原始表中,则可以使用该表。但是,您建议至少有一个gw值有一个单独的列表。您可以明确列出这些内容:

select p.peer, g.gw
from (select distinct peer from t) p cross join
     (values ('GW1'), ('GW2'), ('GW3'), ('GW4')) g(gw) left join
     t
     on t.peer = p.peer and t.gw = g.gw
where t.peer is null;