我有一个表“test_networks”,它是一个网络列表,其中描述了每个网络是什么以及它所在的位置。
CREATE TABLE test_networks
(
id serial PRIMARY KEY,
address cidr,
description text
);
“地址”字段将是以下任何一项:
- 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
我还有一个表“test_systems”,其中包含系统及其属性的列表(我还有一些属性,但这些无关紧要):
CREATE TABLE test_systems
(
id serial PRIMARY KEY,
address inet,
owner text
);
假设我的系统具有以下地址:
- 10.1.1.1
- 10.2.0.1
我想创建所有系统及其最近网络描述的报告(如果未找到网络,则为空描述)。如您所见,10.1.1.1 匹配多个网络,因此我只想为每个系统列出最具体的一个(即具有最高 masklen() 的那个)。示例输出为:
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
我尝试使用此查询:
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;
但是,这会给我一个所有系统+网络对的列表,例如:
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
有谁知道我如何只查询每个系统的最具体的网络?