2016-08-29 208 views
2

我遇到了一些問題檢索使用SQL數據在一個特定的場景中的所有行的行:SQL檢索從其他表

假設我有以下表格:

  • A(ID,attr_a的, attr_b);
  • B(id,attr_d,attr_e);
  • C(id_a,id_b);

正如你可以看到,表CFK引用從表A ID,並從表C引用ID。

我需要檢索表A行,每行A行與每個B行有關。

在真實的生活場景,假設A意味着用戶,B意味着特權,並且C是衆多到涉及用戶與權限的許多實體,我想只得到有所有權限

+1

在a和b上使用inner join? – Baahubali

+0

@ user1490835 a和b沒有關係,所以我不能使用內部連接,並且我只想要A行,它們都具有所有的B ID,所以連接不起作用,它需要更多的限制 –

+1

'a和b沒有關係......是的,他們通過表'C'。 –

回答

1

以下用戶查詢應返回所有A記錄,其中對於給定的ID,它們與B表中的每個記錄匹配。請注意,如果您想返回A中的每條完整記錄,則需要子查詢。

SELECT t1.* 
FROM A t1 
INNER JOIN 
(
    SELECT A.id 
    FROM A 
    INNER JOIN C 
     ON A.id = C.id_a 
    GROUP BY A.id 
    HAVING COUNT(*) = (SELECT COUNT(*) FROM B) 
) t2 
    ON t1.id = t2.id 
2
select A.* 
from A 
join C on id_a = id 
group by id 
having count(id) = (select count(*) from B) 

沒有必要使用一個子查詢,因爲A.id是主鍵(或唯一至少),如通過C.id_a引用的列。

1

假設通過FK約束強制實施參照完整性,所有關鍵列NOT NULL和中的(id_a, id_b)的UNIQUE或PK約束。

如果您只需要ID,只能使用表C。不要浪費時間加入到A

SELECT id_a 
FROM C 
GROUP BY 1 
HAVING count(*) = (SELECT count(*) FROM B); 

如果需要從A列或完整行,加入到它聚集和消除非限定行之後。應該是最快的。

SELECT A.* 
FROM (
    SELECT id_a AS id 
    FROM C 
    GROUP BY 1 
    HAVING count(*) = (SELECT count(*) FROM B) 
    ) c 
JOIN A USING (id); 
0

看起來像你真的只需要表C,如果你想要的是一個具有所有特權的用戶列表。這一種方法是用CONCAT看起來在C.id_aC.id_b之間的配對作爲一個字符串:

SELECT C.id_a 
FROM C 
GROUP BY C.id_a 
HAVING COUNT(DISTINCT CONCAT(C.id_a, C.id_b)) = 
(SELECT COUNT(DISTINCT C.id_b) 
    FROM C) 

這裏測試:http://sqlfiddle.com/#!9/f92a54/3

0

你不需要來算,你只需要檢查(非)存在的行:

SELECT * 
FROM A 
WHERE NOT EXISTS (
     SELECT * FROM B 
     WHERE NOT EXISTS (
       SELECT * FROM C 
       WHERE C.id_a = A.id AND C.id_b = B.id 
       ) 
     );