I have a table "test_networks" that is a list of networks with a description about what each network is and where it is located.
CREATE TABLE test_networks
(
id serial PRIMARY KEY,
address cidr,
description text
);
The field "address" will be any of the following:
- 10.0.0.0/8
- 10.1.0.0/16
- 10.1.1.0/24
- 10.2.0.0/16
- 10.3.0.0/16
- 10.3.1.0/24
- 10.3.2.0/24
- 10.3.3.0/24
- 10.15.1.0/24
- 10.15.2.0/24
- 10.15.3.0/24
I also have a table "test_systems" which contains a list of systems and their properties (I have a few more properties, but those are irrelevant):
CREATE TABLE test_systems
(
id serial PRIMARY KEY,
address inet,
owner text
);
Lets assume I have systems with the following addresses:
I want to create a report of all systems and their closest networks description (or empty description if no network is found). As you can see, 10.1.1.1 matches multiple networks, so I only want to list the most specific one (i.e. the one with the highest masklen()) for each system. Example output would be:
hostaddr | netaddr | description
----------+-------------+----------------
10.1.1.1 | 10.1.1.0/24 | third network
10.2.0.1 | 10.2.0.0/16 | 4th network
I tried using this query:
SELECT s.address AS hostaddr, n.address AS netaddr, n.description AS description
FROM test_systems s
LEFT JOIN test_networks n
ON s.address << n.address;
However, this will give me a list of all system + network pairs, e.g.:
hostaddr | netaddr | description
----------+-------------+----------------
10.1.1.1 | 10.0.0.0/8 | first network
10.1.1.1 | 10.1.0.0/16 | second network
10.1.1.1 | 10.1.1.0/24 | third network
10.2.0.1 | 10.0.0.0/8 | first network
10.2.0.1 | 10.2.0.0/16 | 4th network
Does anyone know how I can query for only the most specific network for each system?