2013-10-27 48 views
0

減號我有以下查詢,相交或在MySQL

SELECT DISTINCT (U.uid) 
FROM users U 
    ,friends F 
WHERE U.STATUS = '1' 
    AND U.uid = F.friend_two 
    AND F.friend_one = '1' 
    AND F.ROLE = 'fri' 

和上面的查詢返回32行。

SELECT DISTINCT (U.uid) 
FROM users U 
    ,friends F 
WHERE U.STATUS = '1' 
    AND U.uid = F.friend_one 
    AND F.friend_two = '1' 
    AND F.ROLE = 'fri' 

而上述查詢返回15行。

我需要合併並取相交結果。相交的行是14行(意味着相同U.uid在兩個表是14行)

+0

這兩個查詢都是**相同**。他們真的在每次運行中返回不同數量的行嗎? – krokodilko

+2

不,他們不是,'friend_one'和'friend_two'被替換。 –

回答

1

嘗試這種情況:

SELECT * 
FROM (
    SELECT DISTINCT (U.uid) UID 
    FROM users U 
     ,friends F 
    WHERE U.STATUS = '1' 
     AND U.uid = F.friend_two 
     AND F.friend_one = '1' 
     AND F.ROLE = 'fri' 
    ) A 
INNER JOIN (
    SELECT DISTINCT (U.uid) UID 
    FROM users U 
     ,friends F 
    WHERE U.STATUS = '1' 
     AND U.uid = F.friend_one 
     AND F.friend_two = '1' 
     AND F.ROLE = 'fri' 
    ) B ON A.UID = B.UID 

這基本上是對用戶ID的交點,作爲指定,二者的你的兩個查詢的結果集。

1

最直接的方式來獲得交集僅僅是加入了查詢:

SELECT uid FROM (
    SELECT DISTINCT U.uid 
    FROM users U JOIN friends F ON F.friend_two=U.uid AND F.friend_one = '1' 
    WHERE U.status='1' AND F.role='fri' 
) NATURAL JOIN (
    SELECT DISTINCT U.uid 
    FROM users U JOIN friends F ON F.friend_one=U.uid AND F.friend_two = '1' 
    WHERE U.status='1' AND F.role='fri' 
) 

但是,您也可以結合查詢和過濾分組結果:

SELECT U.uid 
FROM  users U JOIN friends F ON (
      F.friend_one = U.uid AND F.friend_two = '1' 
     ) OR (
      F.friend_two = U.uid AND F.friend_one = '1' 
     ) 
WHERE U.status='1' AND F.role='fri' 
GROUP BY U.uid 
HAVING SUM(F.friend_one = U.uid AND F.friend_two = '1') 
    AND SUM(F.friend_two = U.uid AND F.friend_one = '1') 
1

如果重寫2查詢與EXISTS而不是加入,您可以先刪除DISTINCT(我假設uid這裏是Users的主鍵),第二,INTERSECTEXCEPT(也稱爲MINUS)操作是清楚的:

查詢1:

SELECT U.uid 
FROM users U 
WHERE U.status = '1' 
    AND EXISTS 
     (SELECT * 
     FROM friends F 
     WHERE U.uid = F.friend_two 
      AND F.friend_one = '1' 
      AND F.ROLE = 'fri' 
    ) ; 

問題2:

SELECT U.uid 
FROM users U 
WHERE U.status = '1' 
    AND EXISTS 
     (SELECT * 
     FROM friends F 
     WHERE U.uid = F.friend_one 
      AND F.friend_two = '1' 
      AND F.ROLE = 'fri' 
    ) ; 

問題3:INTERSECT

SELECT U.uid 
FROM users U 
WHERE U.status = '1' 
    AND EXISTS 
     (SELECT * 
     FROM friends F 
     WHERE U.uid = F.friend_two 
      AND F.friend_one = '1' 
      AND F.ROLE = 'fri' 
    ) 
    AND EXISTS 
     (SELECT * 
     FROM friends F 
     WHERE U.uid = F.friend_one 
      AND F.friend_two = '1' 
      AND F.ROLE = 'fri' 
    ) ; 

查詢4:EXCEPTMINUS

SELECT U.uid 
FROM users U 
WHERE U.status = '1' 
    AND EXISTS 
     (SELECT * 
     FROM friends F 
     WHERE U.uid = F.friend_two 
      AND F.friend_one = '1' 
      AND F.ROLE = 'fri' 
    ) 
    AND NOT EXISTS      -- notice the NOT here 
     (SELECT * 
     FROM friends F 
     WHERE U.uid = F.friend_one 
      AND F.friend_two = '1' 
      AND F.ROLE = 'fri' 
    ) ; 
1

另外兩個版本,值得試一試。
第一個使用半連接,第二個連接friends表。

SELECT distinct(U.uid) 
FROM users U 
JOIN friends F ON U.uid=F.friend_two AND F.friend_one='1' 
WHERE U.status='1' AND F.role='fri' 
    AND EXISTS(
     SELECT 1 FROM friends F1 
     WHERE U.uid=F1.friend_one 
     AND F1.friend_two='1' 
     AND F1.role = 'fri' 
    ) 
; 

SELECT distinct(U.uid) 
FROM users U 
JOIN friends F ON U.uid=F.friend_two AND F.friend_one='1' 
JOIN friends F1 ON U.uid=F1.friend_one AND F1.friend_two='1' 
WHERE U.status='1' AND F.role='fri' AND F1.role = 'fri'