嵌套子查询中的用户父表 ID

Red*_*ies 5 mysql subquery

SELECT users.*,(SELECT COUNT(user_id) AS mutual_connection FROM 
                (SELECT user_id 
                       FROM (
                                SELECT sender_id AS user_id 
                                FROM `connections`
                                WHERE receiver_id=users.id AND status='2' 
                                UNION 
                                SELECT receiver_id AS user_id 
                                FROM `connections` 
                                WHERE sender_id=users.id AND status='2'
                        ) tempUser
                        WHERE user_id IN (
                                  SELECT sender_id AS user_id
                                  FROM `connections` 
                                  WHERE receiver_id='4' AND status='2'
                                  UNION 
                                  SELECT receiver_id AS user_id 
                                  FROM `connections` WHERE sender_id='4' AND status='2') 
                         GROUP BY user_id) 
                as mutualConnection)

     FROM users
Run Code Online (Sandbox Code Playgroud)

错误:

#1054 - 'where 子句'中的未知列'users.id'

如何使用传递值进行子查询

And*_*y M 9

MySQL 禁止引用比一层嵌套更深的外层列。但是,您的查询引用了users.id三个级别的深度。

因此,您需要以这样的方式重写相关子查询,即使它使用嵌套查询,与外层的相关性也不是嵌套的,如下所示:

(
  SELECT
    COUNT(*)
  FROM
    (
      SELECT ...
    ) AS mutualConnection
  WHERE
   ... = users.id
)
Run Code Online (Sandbox Code Playgroud)

由于您的子查询与主查询相关的方式,这项任务是一项相当大的挑战。如果我理解正确,逻辑是这样的:

对于每个用户,找出也连接到某个其他用户(在本例中为 user ID='4')的不同连接(用户)的数量。

因此,您正在检索从两connections列中的任一列收集的列,sender_id并且receiver_id,取决于其他是否匹配users.id。检索后,要检查所检索的sender_idreceiver_id为用户4.最后,将计算所有的连接之间不同结果列的出现(其我将重复,是的混合sender_idreceiver_id)。

这就是您可以在没有尝试的许多嵌套级别并将所有相关性保持在同一级别的情况下执行此操作的方法:

SELECT
  u.*,
  (
    SELECT
      COUNT(DISTINCT CASE u.id WHEN c.sender_id THEN c.receiver_id ELSE c.sender_id END)
    FROM
      connections AS c
    WHERE
      c.status = '2'
      AND u.id IN (c.sender_id, c.receiver_id)
      AND (CASE u.id WHEN c.sender_id THEN c.receiver_id ELSE c.sender_id END)
      IN  (
            SELECT sender_id AS user_id
            FROM   connections 
            WHERE  receiver_id = '4' AND status = '2'
            UNION 
            SELECT receiver_id AS user_id 
            FROM   connections 
            WHERE  sender_id = '4' AND status= '2'
          )
  ) AS mutual_connection_count
FROM
  users AS u
;
Run Code Online (Sandbox Code Playgroud)

CASE 表达式是user_id查询tempUser派生表的列。它用于 COUNT 函数以及 WHERE 子句(IN 谓词)。通常这种重复的代码是通过嵌套来消除的。但是这里不能使用嵌套,因为本文开头提到的 MySQL 限制。因此,代码的重复是您解决它必须付出的代价。幸运的是,在这个特定案例中没有太多。


McN*_*ets 2

您应该将WHERE user_id = users.id子句移至第一个相关子查询。

create table connections(user_id int, sender_id int, receiver_id int, status int);
Run Code Online (Sandbox Code Playgroud)
create table users(id int);
Run Code Online (Sandbox Code Playgroud)
SELECT users.*,
       (SELECT sender_id
        FROM   connections
        WHERE  receiver_id = users.id
       ) 1_level
FROM users;
Run Code Online (Sandbox Code Playgroud)
编号 | 1_level
-: | ------:
SELECT users.*,
       (SELECT sender_id
        FROM   (SELECT receiver_id as sender_id
                FROM   connections
                WHERE  sender_id = users.id
               ) 2_level 
       ) 1_level
FROM users;
Run Code Online (Sandbox Code Playgroud)
“where 子句”中的未知列“users.id”
SELECT users.*,
       (SELECT COUNT(user_id) AS mutual_connection 
        FROM 
             (SELECT user_id 
              FROM 
                   (SELECT sender_id AS user_id 
                    FROM   connections
                    WHERE  status = '2' 
                    UNION 
                    SELECT receiver_id AS user_id 
                    FROM   connections 
                    WHERE  status = '2'
                   ) tempUser
              WHERE user_id IN (SELECT sender_id AS user_id
                                FROM   connections 
                                WHERE  receiver_id = '4' AND status = '2'
                                UNION 
                                SELECT receiver_id AS user_id 
                                FROM   connections 
                                WHERE  sender_id = '4' AND status= '2') 
              GROUP BY user_id) as mutualConnection
        WHERE user_id = users.id  #<<<-------------- Here
       ) uid
FROM users
Run Code Online (Sandbox Code Playgroud)
编号 | uid
-: | --:

dbfiddle在这里