【问题标题】:php PDO MySQL Select results of one table based on array of results from another tablephp PDO MySQL 根据另一个表的结果数组选择一个表的结果
【发布时间】:2016-09-13 19:05:33
【问题描述】:

以下查询将返回所有“阻止者”用户和所有“被阻止”用户。相当直接的查询。

$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();

我需要的是一种从第一个查询的结果中获取所有值的方法,不包括活动的 $username,然后从第二个查询中排除所有这些结果。

例如:

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");

我将如何实现这样的目标?

更新:

所以我尝试使用子查询,但它一直返回“操作数应包含 1 列”

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')

【问题讨论】:

  • 为什么不使用子查询之类的东西来确定不选择什么?
  • @Blake 答案是,因为我不知道该怎么做,这也许是我希望学习的。 :)
  • 当然,如果有人向你扔了一块谷歌骨头,你也可以做到。
  • WHERE 子句中混合使用ANDOR 时,需要非常小心地使用括号,因为AND 的优先级高于OR

标签: php mysql pdo


【解决方案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)
 ) 

【讨论】:

  • 我实际上不认为这会起作用,因为子查询中的多列选择。
  • 具有讽刺意味的是,第一个解决方案不起作用,因为他们从查询中删除了我的第二列选择,而这个解决方案不起作用,因为它返回错误。
  • Bruce,由于您只关心阻塞表中的用户名,请尝试进行联合,这会将两个结果合并为一列。我认为这会奏效。
【解决方案2】:

您也可以为此使用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中的模式

【讨论】:

    猜你喜欢
    • 2015-02-15
    • 1970-01-01
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多