2014-10-07 96 views
0

我有3個表。在第一個表格中,每個項目都有多個條目。第二個基本上是一個映射表。這比這更復雜,但對於這個例子我簡化了。我在表2中檢查了一個簡單的條件。在第三個表中,每個條目都有一個設置爲true或false的標誌。我想返回第一個表上第三個表上的所有匹配行都爲false的行。在下面的例子中,結果將返回項目A b/c表3中Jane和Fred的所有行都是假的,但是沒有其他項目,因爲每個其他項目在表3中至少有一個真實條目。sql查詢加入其中沒有一個滿足條件

Project | Client   name | id   id | active 
    ---------------   ----------------  --------------- 
    A  | Jane   John | 1   1 | false 
    A  | Fred   Jane | 2   1 | true 
    B  | Mary   Fred | 3   2 | false 
    B  | Jane   Mary | 4   2 | false 
    C  | John         3 | false 
    C  | Jane         3 | false 
    D  | Jane         4 | true 
    D  | Mary         4 | false 
    D  | John 
    D  | Fred 
+0

您能否根據您的樣本數據以表格格式提供結果集? – 2014-10-07 16:05:50

回答

1

以下應該做你想要什麼:

select t1.* 
from table1 t1 
where not exists (select 1 
        from table2 t2 join 
         table3 t3 
         on t2.id = t3.id 
        where t2.name = t1.name and t3.active <> false 
       ); 

join之一發生故障時(示例數據中不存在此情況),有什麼不明之處。這將返回該行,因爲即使在這種情況下,第三個表中的所有匹配行也都是false。

0
SELECT t1.* FROM t1 
INNER JOIN t2 ON t1.Client = t2.name 
WHERE t2.id IN (
SELECT id FROM t3 
GROUP BY id, active 
HAVING SUM(CASE active WHEN false THEN 1 ELSE 0 END) = COUNT(1) 
) 
0

你有兩個做選擇從第一個表聯接和一個簡單的WHERE條件:

SELECT 
    res.Project 
FROM 
    (SELECT 
     table1.Project, 
     BOOL_OR(res) as active 
    FROM 
     table1 
     JOIN table2 ON table2.name=table1.Client 
     JOIN table3 ON table3.id=table2.id 
    GROUP BY table1.Project 
    ) as res 
WHERE 
    res.active=FALSE 
+0

這將返回所有存在假標誌的地方,即使還有一個真標誌。 – RememberME 2014-10-07 16:14:14

+0

編輯我的答案。以前的SQL像「active」字段的子查詢分組一樣使用。 – dmikam 2014-10-08 07:53:29

0

一個相當直接的加入與HAVING應該給你你想要的結果;

SELECT t1.project, t1.client 
FROM table1 t1 
JOIN table2 t2 ON t1.client = t2.name 
JOIN table3 t3 ON t2.id = t3.id 
GROUP BY t1.project, t1.client 
HAVING NOT MAX(t3.active) 

An SQLfiddle to test with

這基本上只是直接連接所有表,按客戶端和項目對結果進行分組。然後它使用NOT MAX(t3.active)來檢查組中所有布爾值是否爲假。

該版本選擇不返回沒有任何活動標誌的客戶端/項目進行檢查。