2011-01-27 76 views
2

說我有這樣的查詢排除行基於其他行(SQL)

TABLE 
ID | DATA | VAL 
=============== 
01 | ABCD | 1 
01 | DEFG | 2 
02 | FGHI | 3 
02 | HIJK | 2 
03 | JKLM | 3 
03 | LMNO | 4 
04 | NOPQ | 0 
04 | PQRS | 1 

目前,我有一個試圖找到唯一的好值的查詢像這樣,但它有缺陷,因爲其他行中具有不良VAL的ID被包括在內,這不是我想要的。

SELECT * 
FROM TABLE 
WHERE TABLE.VAL IN ("1","2","3") 

將返回這個(與LMNO PQRS和遺漏):

TABLE 
ID | DATA | VAL 
=============== 
01 | ABCD | 1 
01 | DEFG | 2 
02 | FGHI | 3 
02 | HIJK | 2 
03 | JKLM | 3 
04 | NOPQ | 0 

但是,我只希望在ID無不良值的行。所以,01和02都很好,因爲他們所有的行都有很好的結果。 03和04是不好的,因爲它們被其他行中的不好結果所污染。

我可以像這樣把結果帶入軟件,然後用軟件處理它,但似乎這對數據庫來說應該是可能的,並且作爲一般規則,在數據庫上執行它比在軟件中更好(你知道,這是一種他們在那裏爲...什麼)

我能想出的最好的是這樣的:

SELECT * 
FROM TABLE 
WHERE COUNT(SELECT ID 
      FROM TABLE 
      WHERE TABLE.VAL NOT IN ("1","2","3") 
      ) = 0 

這是可行的?有更好的選擇嗎?

謝謝!

+0

對於什麼數據庫和版本? – 2011-01-28 00:25:33

回答

4

用途:

SELECT * 
    FROM TABLE a 
WHERE a.val IN (1,2,3) 
    AND NOT EXISTS(SELECT NULL 
        FROM TABLE b 
        WHERE b.id = a.id 
        AND b.val NOT IN (1, 2, 3)) 
1

您可以使用減號運算符。

僞查詢

select everything 
from tables 
where id in (select id from table minus select id from table where val is bad) 
+0

似乎優雅:) – corsiKa 2011-01-28 00:02:45

+0

MINUS是Oracle特有的,不是嗎? ANSI將是例外 – 2011-01-28 00:21:42

1

你可以嘗試像

SELECT * 
FROM TABLE 
WHERE TABLE.ID NOT IN(
    SELECT ID 
    FROM TABLE 
    WHERE TABLE.VAL < '1' 
    OR TABLE.VAL > '3' 
) 
+0

我不保證連續數字:( – corsiKa 2011-01-28 00:13:18

+0

以及你只是將大於/小於有效範圍的子查詢更改爲WHERE IN(壞值) – WebChemist 2011-01-28 00:19:25

1

這裏是另一種替代方案,將通過TBL一次,骨料,並使用發現的ID,從TBL檢索數據

SELECT * 
WHERE ID IN 
(
    SELECT 
     ID, 
     CASE WHEN val in (1,2,3) THEN 1 ELSE 0 END Test 
    FROM TBL 
    GROUP BY ID 
    HAVING MIN(val) = 1 
) 

對於多列鍵,並且作爲上述IN表單的替代方法,可以使用JOIN表單。

SELECT T.* 
FROM (
    SELECT 
     Company, OrderNumber, 
     CASE WHEN val in (1,2,3) THEN 1 ELSE 0 END Test 
    FROM TBL 
    GROUP BY Company, OrderNumber 
    HAVING MIN(val) = 1 
    ) KEEP 
INNER JOIN TBL T ON T.Company = KEEP.Company and T.OrderNumber=KEEP.OrderNumber