2016-09-13 41 views
0

以下查詢將返回所有「阻止」用戶和所有「阻止」用戶。相當直接的查詢。php PDO MySQL根據另一個表的結果數組選擇一個表的結果

$stmt=$db->prepare('SELECT blocker,blocked FROM list_blocked 
        WHERE (blocked = :username AND blocker <> :username) 
        OR (blocker = :username AND blocked <> :username)'); 
$stmt->bindParam(':username', $username); 
$stmt->execute(); 

下一個查詢將從members表中返回除當前$ username以外的所有用戶名。

$query = $db->prepare("SELECT username FROM members WHERE username <> :username"); 
$query->bindValue(':user', $username; 
$query->execute(); 
$row = $query->fetchAll(); 

我需要的是一種方式來獲得第一個查詢的結果,不包括主動$用戶名中的所有值,然後排除從第二查詢所有這些結果。

因此,例如:

Example results of first query: 
jim blocked joe 
larry blocked joe 
steve blocked joe 
joe blocked tony 
jack blocked joe 

Those results applied to the second query would look something like: 
$query = $db->prepare("SELECT username FROM members WHERE username <> :username 
         AND username <> jim 
         AND username <> larry 
         AND username <> steve 
         AND username <> tony 
         AND username <> jack"); 

我究竟是如何將實現這樣的事情?

UPDATE:

所以我試圖用一個子查詢,但它一直返回「操作數應包含1列(S)」

SELECT username FROM members WHERE username NOT IN (
    SELECT blocker,blocked FROM list_blocked 
          WHERE (blocked = 'viraladmin' AND blocker <> 'viraladmin') 
          OR (blocker = 'viraladmin' AND blocked <> 'viraladmin') 
) 

另一個更新:

我試圖使用一個內部聯接來實現這一點,但結果總是返回空的,我認爲這是因爲在那裏實際上沒有什麼可參加的。

SELECT members.username, list_blocked.blocker, list_blocked.blocked 
FROM members 
INNER JOIN list_blocked 
ON members.username = list_blocked.blocker 
AND members.username = list_blocked.blocked 
WHERE members.username <> 'username' 
AND (list_blocked.blocked = 'username' AND list_blocked.blocker <> 'username') 
OR (list_blocked.blocker = 'username' AND list_blocked.blocked <> 'username') 
+0

模式爲什麼不使用類似的子查詢,以確定哪些不選擇? – Blake

+0

@布萊克那麼答案是,因爲我不知道該怎麼做,那也許是我希望學習的東西。 :) – Bruce

+0

當然,如果有人把你的谷歌骨頭,你可以做到。 – Blake

回答

1

你可以做到這一點使用子查詢:

SELECT username FROM members WHERE username NOT IN (
SELECT blocker,blocked FROM list_blocked 
       WHERE (blocked = :username AND blocker <> :username) 
       OR (blocker = :username AND blocked <> :username) 
) 

編輯 - 以適應SQL查詢你需要工會在子查詢這樣的成績再回來接着一列。 :

SELECT username FROM members WHERE username NOT IN (
    SELECT blocker as username FROM list_blocked 
       WHERE (blocked = :username AND blocker <> :username) 
       OR (blocker = :username AND blocked <> :username) 
    UNION 
    SELECT blocked as username FROM list_blocked 
       WHERE (blocked = :username AND blocker <> :username) 
       OR (blocker = :username AND blocked <> :username) 
) 
+1

我其實不認爲這會因爲子查詢中的多列選擇而起作用。 – Blake

+0

具有諷刺意味的是,第一個解決方案無法正常工作,因爲他們從查詢中刪除了我的第二列選擇,並且此解決方案無效,因爲它會返回錯誤。 – Bruce

+0

布魯斯,因爲你只關心來自阻塞表的用戶名,請嘗試做一個聯合,它將把這兩個結果作爲一個單獨的列加​​入。我認爲這將起作用。 – Zack

0

您也可以使用LEFT JOIN - NULL模式。

SELECT username 
FROM members AS m 
LEFT JOIN list_blocked AS b 
ON m.username IN (b.blocker, b.blocked) 
    AND ((blocked = :username AND blocker <> :username) 
     OR (blocker = :username AND blocked <> :username)) 
WHERE b.blocked IS NULL 

這是基於Return row only if value doesn't exist

相關問題