如果子查询 returns 有任何结果,如何 return 布尔值

How to return boolean value if sub-query returns any result

我正在尝试编写一个查询来根据 table 个重叠网络块审核 table 个 IP 地址。可以通过 BOOLEAN 将单个网络块标记为活动或非活动。根据 netblock table 中的活动列,审计查询应该 return 一个布尔值 active。如果任何网络块的 active 列设置为 FALSE,则网络块中包含的 IP 地址应报告为 active 设置为 FALSE。

下面是iptable的定义:

CREATE TABLE IF NOT EXISTS ip
(  
   address          INET            NOT NULL UNIQUE,
   modified         timestamp       WITH TIME ZONE NOT NULL
                                    DEFAULT TIMESTAMP 'epoch',
   username         VARCHAR(64),
   acctSession      VARCHAR(32),
   nasId            INTEGER,
   PRIMARY KEY      ( address ),
   FOREIGN KEY      ( nasId )
      REFERENCES    nas
                    ( id )
);

以下是 ip 中的示例条目:

radius_ippool=> SELECT * FROM ip ORDER BY address;
   address    |           modified            |      username      |       acctsession       | nasid
--------------+-------------------------------+--------------------+-------------------------+-------
 209.193.4.0  | 1970-01-01 00:00:00-10        |                    |                         |
 209.193.4.1  | 1970-01-01 00:00:00-10        |                    |                         |
 209.193.4.2  | 1970-01-01 00:00:00-10        |                    |                         |
 209.193.4.3  | 1970-01-01 00:00:00-10        |                    |                         |
 209.193.4.4  | 1970-01-01 00:00:00-10        |                    |                         |
 209.193.4.5  | 1970-01-01 00:00:00-10        |                    |                         |
 209.193.4.6  | 1970-01-01 00:00:00-10        |                    |                         |
 209.193.4.7  | 1970-01-01 00:00:00-10        |                    |                         |
 209.193.4.8  | 2019-05-09 11:55:20.456856-08 | jdoe8@example.net  | aqaqqaasdqweaasdqa8     |     3
 209.193.4.9  | 2019-05-09 11:55:20.638136-08 | jdoe9@aexample.net | qweadszcxqweasdzcx9     |     3
 209.193.4.10 | 2019-05-09 11:55:20.85176-08  | jdoe10@example.net | user:jdoe10@example.net |     3
 209.193.4.11 | 2019-05-09 11:55:20.872469-08 | jdoe11@example.net | user:jdoe11@example.net |     3
 209.193.4.12 | 2019-05-09 11:55:20.894765-08 | jdoe12@example.net | user:jdoe12@example.net |     3
 209.193.4.13 | 2019-05-09 11:55:21.02472-08  | jdoe13@example.net | user:jdoe13@example.net |     3
 209.193.4.14 | 1970-01-01 00:00:00-10        |                    |                         |
 209.193.4.15 | 1970-01-01 00:00:00-10        |                    |                         |
(16 rows)

下面是netblocktable的定义:

CREATE TABLE IF NOT EXISTS netblock
(  
   id               SERIAL,
   network          CIDR            NOT NULL UNIQUE,
   poolId           INTEGER         NOT NULL,
   regionId         INTEGER,
   active           BOOLEAN         NOT NULL DEFAULT TRUE,
   description      VARCHAR(256),
   PRIMARY KEY      ( id ),
   FOREIGN KEY      ( poolId )
      REFERENCES    pool
                    ( id ),
   FOREIGN KEY      ( regionId )
      REFERENCES    region
                    ( id )
);

以下是 netblock table 中的示例条目:

radius_ippool=> SELECT * FROM netblock ORDER BY network;
 id |    network     | poolid | regionid | active |              description
----+----------------+--------+----------+--------+----------------------------------------
  1 | 209.193.4.0/28 |      1 |        2 | t      |
  2 | 209.193.4.0/29 |      1 |        2 | f      | Reserved for engineering test accounts
  4 | 209.193.4.4/30 |      1 |        2 | t      |
(3 rows)

我想出一个查询来在单独的查询中列出所有 "active" 和 "inactive" IP 地址:

-- query to return "inactive" IP addresses
SELECT DISTINCT      netblock.regionId AS  regionId,
                     ip.address        AS  ipAddress,
                     netblock.active   AS  active
   FROM              ip
   INNER JOIN        netblock
      ON             ip.address        <<= netblock.network
   WHERE             netblock.active   =   FALSE
   ORDER BY          ipAddress;

-- query to return "active" IP addresses
SELECT DISTINCT      netblock.regionId AS  regionId,
                     ip.address        AS  ipAddress,
                     netblock.active   AS  active
   FROM              ip
   INNER JOIN        netblock       
      ON             ip.address        <<= netblock.network
   WHERE             netblock.active   =   TRUE
      AND            ip.address             NOT IN
                     (
                       SELECT          address AS ipAddress
                          FROM         ip
                          INNER JOIN   netblock
                             ON        ip.address          <<= netblock.network
                                AND    netblock.active     =   FALSE
                     )
   ORDER BY          ipAddress;

以上查询结果:

 regionid |  ipaddress  | active
----------+-------------+--------
        2 | 209.193.4.0 | f
        2 | 209.193.4.1 | f
        2 | 209.193.4.2 | f
        2 | 209.193.4.3 | f
        2 | 209.193.4.4 | f
        2 | 209.193.4.5 | f
        2 | 209.193.4.6 | f
        2 | 209.193.4.7 | f
(8 rows)

 regionid |  ipaddress   | active
----------+--------------+--------
        2 | 209.193.4.8  | t
        2 | 209.193.4.9  | t
        2 | 209.193.4.10 | t
        2 | 209.193.4.11 | t
        2 | 209.193.4.12 | t
        2 | 209.193.4.13 | t
        2 | 209.193.4.14 | t
        2 | 209.193.4.15 | t
(8 rows)

如何通过为 inactvie/active net 排队 netblock table 来替换以下 table 中 active 列的静态值 unknown块?

SELECT DISTINCT      netblock.regionId AS regionId,
                     ip.address        AS address,
                     'unknown'         AS active,
                     (
                       nasId           IS NOT NULL
                       OR
                       acctSession     IS NOT NULL
                     )                 AS assigned,
                     ip.modified       AS modified,
                     ip.nasid          AS nasId,
                     ip.username       AS username,
                     ip.acctSession    AS acctSession
   FROM              ip
   INNER JOIN        netblock
      ON             ip.address        <<= netblock.network
   ORDER BY          address;

上述查询的结果:

 regionid |   address    | active  | assigned |           modified            | nasid |      username      |       acctsession
----------+--------------+---------+----------+-------------------------------+-------+--------------------+-------------------------
        2 | 209.193.4.0  | unknown | f        | 1970-01-01 00:00:00-10        |       |                    |
        2 | 209.193.4.1  | unknown | f        | 1970-01-01 00:00:00-10        |       |                    |
        2 | 209.193.4.2  | unknown | f        | 1970-01-01 00:00:00-10        |       |                    |
        2 | 209.193.4.3  | unknown | f        | 1970-01-01 00:00:00-10        |       |                    |
        2 | 209.193.4.4  | unknown | f        | 1970-01-01 00:00:00-10        |       |                    |
        2 | 209.193.4.5  | unknown | f        | 1970-01-01 00:00:00-10        |       |                    |
        2 | 209.193.4.6  | unknown | f        | 1970-01-01 00:00:00-10        |       |                    |
        2 | 209.193.4.7  | unknown | f        | 1970-01-01 00:00:00-10        |       |                    |
        2 | 209.193.4.8  | unknown | t        | 2019-05-09 11:55:20.456856-08 |     3 | jdoe8@example.net  | aqaqqaasdqweaasdqa8
        2 | 209.193.4.9  | unknown | t        | 2019-05-09 11:55:20.638136-08 |     3 | jdoe9@aexample.net | qweadszcxqweasdzcx9
        2 | 209.193.4.10 | unknown | t        | 2019-05-09 11:55:20.85176-08  |     3 | jdoe10@example.net | user:jdoe10@example.net
        2 | 209.193.4.11 | unknown | t        | 2019-05-09 11:55:20.872469-08 |     3 | jdoe11@example.net | user:jdoe11@example.net
        2 | 209.193.4.12 | unknown | t        | 2019-05-09 11:55:20.894765-08 |     3 | jdoe12@example.net | user:jdoe12@example.net
        2 | 209.193.4.13 | unknown | t        | 2019-05-09 11:55:21.02472-08  |     3 | jdoe13@example.net | user:jdoe13@example.net
        2 | 209.193.4.14 | unknown | f        | 1970-01-01 00:00:00-10        |       |                    |
        2 | 209.193.4.15 | unknown | f        | 1970-01-01 00:00:00-10        |       |                    |
(16 rows)

您可以使用 ALL 和子查询来检查 IP 所在的所有网络块是否都处于活动状态。

SELECT ...
       true = ALL (SELECT nb2.active
                          FROM netblock nb2
                          WHERE ip.address <<= nb2.network) active,
       ...

或者您可以使用 NOT EXISTS:

SELECT ...
       NOT EXISTS (SELECT *
                          FROM netblock nb2
                          WHERE ip.address <<= nb2.network
                                AND NOT nb2.active) active,
       ...