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'
如何使用传递值进行子查询
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_id或receiver_id为用户4.最后,将计算所有的连接之间不同结果列的出现(其我将重复,是的混合sender_id和receiver_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 限制。因此,代码的重复是您解决它必须付出的代价。幸运的是,在这个特定案例中没有太多。
您应该将WHERE user_id = users.id子句移至第一个相关子查询。
Run Code Online (Sandbox Code Playgroud)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;编号 | 1_level -: | ------:
Run Code Online (Sandbox Code Playgroud)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;“where 子句”中的未知列“users.id”
Run Code Online (Sandbox Code Playgroud)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编号 | uid -: | --:
dbfiddle在这里
| 归档时间: |
|
| 查看次数: |
15729 次 |
| 最近记录: |