2016-04-25 40 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