2016-04-25 50 views
0

将它们分组实现了同一行值选取所有列,具有特定特征,同子数据我有下一个结构的表:通过在Oracle

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 | 

我想选择所有的行/数据考虑到由CONNECTION列定义的组为AAA,BBB和CCC组,查询必须仅选择具有值'N'的STATE列的所有行的组,但始终考虑该组的所有数据。 所以餐桌上的结果将是:

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

我一直在寻找的功能,如解码,存在等,但就是不明白怎么解决这个问题。

任何想法,我怎么可以为此写一个查询?

+0

非常感谢你的所有。我试过_Felix Pamittan_答案,它工作正常。 – Albert

+0

所有3种解决方案都应该可以工作,但[Giorgos Betsos'Answer](http://stackoverflow.com/a/36834763/1509264)只会扫描一次表格/索引,而使用“IN”或“NOT EXISTS”和相关的子-query将扫描子查询中和外部查询中的表/索引,并可能会执行更多的IO。如果您查看两个查询的解释计划,则可以自行计算表(或索引)扫描的数量,并可以查看每个解决方案的不同IO数量。 – MT0

回答

0

您可以使用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没有其他STATE s比'N'

+0

SUM(case when state ='N'THEN 1 ELSE 0 END)> 0'是多余的,因为必须存在至少一个要分组的行,并且您已使用SUM(CASE WHEN STATE <>'N'THEN 1 ELSE 0 END)= 0'过滤器。 – MT0

1

试试这个:

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 
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


或相关性高苏bquery:

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