Select 所有具有特定特征的行,通过在 oracle 中通过相同的行值对它们进行分组,具有相同的子数据

Select all rows, with specific characteristics, with same subdata by grouping them through a same row value in oracle

我有一个 table 具有下一个结构:

Data structure: 
| CONTRACT | CONNECTION | STATE |
|    1     |    AAA     |   Y   |
|    2     |    AAA     |   Y   |
|    3     |    BBB     |   N   |
|    4     |    BBB     |   N   |
|    5     |    BBB     |   N   |
|    6     |    BBB     |   N   |
|    7     |    AAA     |   Y   |
|    8     |    CCC     |   Y   |
|    9     |    CCC     |   N   |
|    10    |    AAA     |   Y   |
|    11    |    CCC     |   N   |

我想 select 所有 rows/data 考虑到由 CONNECTION 列定义为组 AAA、BBB 和 CCC 的组,查询必须 select 只有具有具有值 'N' 的 STATE 列的 all 行,但始终考虑该组的所有数据。 所以 table 的结果将是:

Result needed: 
| CONTRACT | CONNECTION | STATE |
|    3     |    BBB     |   N   |
|    4     |    BBB     |   N   |
|    5     |    BBB     |   N   |
|    6     |    BBB     |   N   |

我一直在寻找解码、存在等函数,但就是不知道如何解决这个问题。

知道如何为此目的编写查询吗?

您可以使用 SUMHAVING:

ONLINE DEMO

SELECT *
FROM tbl t
WHERE
    CONNECTION IN(
        SELECT CONNECTION
        FROM tbl
        GROUP BY CONNECTION
        HAVING
            SUM(CASE WHEN STATE = 'N' THEN 1 ELSE 0 END) > 0
            AND SUM(CASE WHEN STATE <> 'N' THEN 1 ELSE 0 END) = 0
    )

HAVING 子句中的第一个条件确保 CONNECTION 至少有一个 STATE = 'N'。第二个确保 CONNECTION 除了 'N'.

没有其他 STATE

试试这个:

SELECT CONTRACT, CONNECTION, STATE
FROM (
  SELECT CONTRACT, CONNECTION, STATE,
         COUNT(CASE WHEN STATE <> 'N' THEN 1 END) OVER (PARTITION BY CONNECTION) AS cnt
  FROM mytable) t
WHERE t.cnt  = 0

你可以使用窗口化 COUNT:

WITH cte AS (
  SELECT *
   ,COUNT(CASE WHEN STATE = 'N' THEN 1 END) OVER(PARTITION BY CONNECTION) AS num_of_n
   ,COUNT(CASE WHEN STATE <> 'N' OR STATE IS NULL THEN 1 END) 
          OVER(PARTITION BY CONNECTION) AS num_of_non_n
  FROM mytable
)
SELECT CONTRACT, CONNECTION, STATE
FROM cte
WHERE num_of_n > 0 AND num_of_non_n = 0;

LiveDemo


或相关子查询:

SELECT *
FROM mytable m1
WHERE STATE = 'N'
  AND NOT EXISTS (SELECT 1
                  FROM mytable m2
                  WHERE m1.CONNECTION = m2.CONNECTION
                    AND (STATE <> 'N' OR STATE IS NULL));

LiveDemo 2