2010-06-15 61 views
2

(不是我真正的MySQL架構,但說明了什麼需要做。)查找組,兩者都驗證的,未經驗證的用戶

用戶可以屬於多個組和組之間都有許多用戶。

users: 
    id INT 
    validated TINYINT(1) 

groups: 
    id INT 
    name VARCHAR(20) 

groups_users: 
    group_id INT 
    user_id INT 

我需要找到一個既包含驗證和未經驗證的用戶(validated分別爲10)組,以執行特定的手動維護任務。有成千上萬的用戶,都屬於至少一個組,但一個組通常只有2-5個用戶。

這是一個實時生產服務器,所以我可能自己製作一個查詢,但最後一個我嘗試了幾分鐘後才殺死它。 (我不是那些傑出的SQL嚮導之一)。我想我可以將服務器關閉以進行維護,但是,如果可能的話,在幾秒鐘內完成此任務的查詢將非常棒。

謝謝!

回答

1

對於每個用戶,選擇與他在同一組中的所有用戶。然後只選擇驗證不同的用戶。

SELECT users u1 LEFT JOIN groups_users g1 ON id=user_id LEFT JOIN groups_users g2 ON group_id=group_id LEFT JOIN users u2 ON user_id=id WHERE u1.validated=1 AND u2.validated=0; 
1

下面是一個完整的例子(我做到了在Oracle中,但主要的SQL查詢應該可以正常上MySql)。

CREATE TABLE USERS (ID INTEGER, validated NUMBER(1)); 
CREATE TABLE GROUPS (ID integer, NAME VARCHAR2(20)); 
CREATE TABLE groups_users (group_id integer, user_id INTEGER); 

INSERT INTO USERS VALUES(1,0); 
INSERT INTO USERS VALUES(1,1); 
INSERT INTO USERS VALUES(2,0); 
INSERT INTO USERS VALUES(3,0); 
INSERT INTO USERS VALUES(3,1); 

INSERT INTO GROUPS VALUES(1,'g1'); 
INSERT INTO GROUPS VALUES(2,'g2'); 
INSERT INTO GROUPS VALUES(3,'g3'); 

INSERT INTO groups_users VALUES (1,1); 
INSERT INTO groups_users VALUES (2,2); 
INSERT INTO groups_users VALUES (3,3); 

SELECT 
DISTINCT g.id 
    FROM groups g 
    WHERE 
      EXISTS (SELECT * 
        FROM GROUPS_USERS gu 
         , USERS u 
        WHERE gu.user_id = u.id 
        AND gu.group_id = g.id 
        AND u.validated = 0) 
    AND EXISTS (SELECT * 
        FROM GROUPS_USERS gu 
         , USERS u 
        WHERE gu.user_id = u.id 
        AND gu.group_id = g.id 
        AND u.validated = 1) 

結果(組1和3具有已驗證和未經驗證用戶):

1, 3