嵌套加入子查询和失败关联
Nested Join in Subquery and failing correlation
我有 3 tables sc_user, sc_cube, sc_cube_sent
我想加入一个用户查询(sc_user)一个不同的随机 message/cube(来自 sc_cube),之前没有发送给该用户(sc_cube_sent),所以结果集中的每一行都有一个不同的用户 ID 和一个来自 sc_cube 的随机立方体 ID,它不属于 sc_cube_sent 的一部分,与那里关联的用户 ID。
我面临的问题是,我似乎无法在内部 On 子句中需要外部查询的 u.id 的情况下使用相关 ID。我需要评论部分才能使其正常工作。
# get one random idcube per user not already sent to that user
SELECT u.id, sub.idcube
FROM sc_user as u
LEFT JOIN (
SELECT c.idcube, sent.idreceiver FROM sc_cube c
LEFT JOIN sc_cube_sent sent ON ( c.idcube = sent.idcube /* AND sent.idreceiver = u.id <-- "unknown column u.id in on clause" */ )
WHERE sent.idcube IS NULL
ORDER BY RAND()
LIMIT 1
) as sub
ON 1
我添加了一个 fiddle 和一些数据:http://sqlfiddle.com/#!9/7b0bc/1
应为用户 1 显示的新 cubeids ( sc_cube ) 如下:2150、2151、2152、2153
编辑>>
我可以用另一个子查询而不是连接来完成它,但这会对性能产生巨大影响并且不可行(每个 table 上的几千行上有 30 秒+合理实现的键),所以我仍在寻找一种将解决方案与 JOIN 一起使用的方法。
SELECT
u.id,
(SELECT sc_cube.idcube
FROM sc_cube
WHERE NOT EXISTS(
SELECT sc_cube.idcube FROM sc_cube_sent WHERE sc_cube_sent.idcube = sc_cube.idcube AND sc_cube_sent.idreceiver = u.id
)
ORDER BY RAND() LIMIT 0,1
) as idcube
FROM sc_user u
无法对此进行测试,我会说您需要将 sc_user 包含在子查询中,因为您丢失了范围
LEFT JOIN
( SELECT c.idcube, sent.idreceiver
FROM sc_user u
JOIN sc_cube c ON c.whatever_your_join_column_is = u.whatever_your_join_column_is
LEFT JOIN sc_cube_sent sent ON ( c.idcube = sent.idcube AND sent.idreceiver = u.id )
WHERE sent.idcube IS NULL
ORDER BY RAND()
LIMIT 1
) sub
如果您想获取 尚未发送给特定用户 的消息 ID,那么为什么要使用连接或左连接?
只要做:
SELECT sent.idcube
FROM sc_cube_sent sent
WHERE sent.idreceiver <> u.id
那么查询可能如下所示:
SELECT u.id,
/* sub.idcube */
( SELECT sent.idcube
FROM sc_cube_sent sent
WHERE sent.idreceiver <> u.id
ORDER BY RAND()
LIMIT 1
) as idcube
FROM sc_user as u
在 on 子句中使用 NOT IN subselect 使其工作。尽管相关性 link u.id 未在 LEFT JOIN 范围内给出,但它适用于 ON 子句的范围。这是它的工作原理:
SELECT u.id, sub.idcube
FROM sc_user as u
LEFT JOIN (
SELECT idcube FROM sc_cube c ORDER BY RAND()
) sub ON (
sub.idcube NOT IN (
SELECT s.idcube FROM sc_cube_sent s WHERE s.idreceiver = u.id
)
)
GROUP BY u.id
Fiddle : http://sqlfiddle.com/#!9/7b0bc/48
我有 3 tables sc_user, sc_cube, sc_cube_sent
我想加入一个用户查询(sc_user)一个不同的随机 message/cube(来自 sc_cube),之前没有发送给该用户(sc_cube_sent),所以结果集中的每一行都有一个不同的用户 ID 和一个来自 sc_cube 的随机立方体 ID,它不属于 sc_cube_sent 的一部分,与那里关联的用户 ID。
我面临的问题是,我似乎无法在内部 On 子句中需要外部查询的 u.id 的情况下使用相关 ID。我需要评论部分才能使其正常工作。
# get one random idcube per user not already sent to that user
SELECT u.id, sub.idcube
FROM sc_user as u
LEFT JOIN (
SELECT c.idcube, sent.idreceiver FROM sc_cube c
LEFT JOIN sc_cube_sent sent ON ( c.idcube = sent.idcube /* AND sent.idreceiver = u.id <-- "unknown column u.id in on clause" */ )
WHERE sent.idcube IS NULL
ORDER BY RAND()
LIMIT 1
) as sub
ON 1
我添加了一个 fiddle 和一些数据:http://sqlfiddle.com/#!9/7b0bc/1 应为用户 1 显示的新 cubeids ( sc_cube ) 如下:2150、2151、2152、2153
编辑>>
我可以用另一个子查询而不是连接来完成它,但这会对性能产生巨大影响并且不可行(每个 table 上的几千行上有 30 秒+合理实现的键),所以我仍在寻找一种将解决方案与 JOIN 一起使用的方法。
SELECT
u.id,
(SELECT sc_cube.idcube
FROM sc_cube
WHERE NOT EXISTS(
SELECT sc_cube.idcube FROM sc_cube_sent WHERE sc_cube_sent.idcube = sc_cube.idcube AND sc_cube_sent.idreceiver = u.id
)
ORDER BY RAND() LIMIT 0,1
) as idcube
FROM sc_user u
无法对此进行测试,我会说您需要将 sc_user 包含在子查询中,因为您丢失了范围
LEFT JOIN
( SELECT c.idcube, sent.idreceiver
FROM sc_user u
JOIN sc_cube c ON c.whatever_your_join_column_is = u.whatever_your_join_column_is
LEFT JOIN sc_cube_sent sent ON ( c.idcube = sent.idcube AND sent.idreceiver = u.id )
WHERE sent.idcube IS NULL
ORDER BY RAND()
LIMIT 1
) sub
如果您想获取 尚未发送给特定用户 的消息 ID,那么为什么要使用连接或左连接?
只要做:
SELECT sent.idcube
FROM sc_cube_sent sent
WHERE sent.idreceiver <> u.id
那么查询可能如下所示:
SELECT u.id,
/* sub.idcube */
( SELECT sent.idcube
FROM sc_cube_sent sent
WHERE sent.idreceiver <> u.id
ORDER BY RAND()
LIMIT 1
) as idcube
FROM sc_user as u
在 on 子句中使用 NOT IN subselect 使其工作。尽管相关性 link u.id 未在 LEFT JOIN 范围内给出,但它适用于 ON 子句的范围。这是它的工作原理:
SELECT u.id, sub.idcube
FROM sc_user as u
LEFT JOIN (
SELECT idcube FROM sc_cube c ORDER BY RAND()
) sub ON (
sub.idcube NOT IN (
SELECT s.idcube FROM sc_cube_sent s WHERE s.idreceiver = u.id
)
)
GROUP BY u.id
Fiddle : http://sqlfiddle.com/#!9/7b0bc/48