Home > Net >  SQL query showing which entries lack rows defined in another table (exception report)
SQL query showing which entries lack rows defined in another table (exception report)

Time:04-27

Using postgres I am trying to write a query that will show me which devices do not have all access-list entries defined on them.

The table net_schema.acl_ssh defines the master list of ACL entries that all devices should have:

addr
10.10.10.10
20.20.20.20
30.30.30.30

The table net_config.acl contains the ACL entries that each device has:

hostname acl_id src_addr
sw01 ssh 10.10.10.10
sw01 ssh 30.30.30.30
sw02 ssh 10.10.10.10
sw02 ssh 20.20.20.20
sw02 ssh 30.30.30.30

The table net_inv.master is my inventory table of all devices:

hostname ip
sw01 192.168.1.1
sw02 192.168.1.2
sw03 192.168.1.3

The query should return device "sw01" since it is missing entry "20.20.20.20" and "sw03" since it's missing all ACL entries.

CodePudding user response:

I usually shy away from select distinct, but this seems like a reasonable use case if ever there was one.

I'm effectively using the left join to find entities where an inner join would fail.

select distinct
  i.hostname
from
  net_inv.master i
  cross join net_schema.acl_ssh s
  left join net_config.acl a on
    i.hostname = a.hostname and
    s.addr = a.src_addr
where
  a.hostname is null

For some background/explanation, this query gives you the full output, so you can see why the where condition followed by distinct narrows it down to the ones missing entries:

select *
from
  net_inv.master i
  cross join net_schema.acl_ssh s
  left join net_config.acl a on
    i.hostname = a.hostname and
    s.addr = a.src_addr

CodePudding user response:

I would blow out the hostname and src_addr combinations with a cross join and then use an except to find the missing records:

with needed as (
  select m.hostname, 'ssh' as acl_id, s.addr as src_addr
    from net_inv.master m
         cross join net_schema.acl_ssh s
)
select hostname, acl_id, src_addr from net_schema.acl
except
select hostname, acl_id, src_addr from needed;
  • Related