我有以下数据库表
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,永远不会超过此数量
答案 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;