是否可以在 JOIN 中使用占位符?
Is it possible to use placeholders in JOIN?
我有以下 SQL 查询,用于输出论坛 posts 与 posts 的关系 tables 中的相关数据(用户 post编辑它,forum/thread 它是 etc 的子项)。
我正在使用 PDO 位置占位符(因此是 ?)
SELECT {Lots of select stuff here}
FROM tab_posts tposts
INNER JOIN tab_users tuser ON tuser.id=?
INNER JOIN tab_users tusers ON tposts.user_id=tusers.id
INNER JOIN tab_ranks tranks ON tusers.rank_id=tranks.id
INNER JOIN tab_avatars tavatars ON tusers.avatar_id=tavatars.id
INNER JOIN tab_threads tthreads ON tposts.thread_id=tthreads.id
INNER JOIN tab_forums tforums ON tthreads.forum_id=tforums.id
WHERE tposts.thread_id=? AND tforums.rank_id <= tuser.rank_id
所以在这个查询中我使用了 2 个占位符,第一个是从会话中检索到的用户 ID,另一个是从请求中检索到的线程 ID(以确保我们只列出 posts 属于该线程)。
tuser
是会话用户,tusers
是提交 post 的用户的别名。我只需要 tuser
检查会话用户是否被允许查看那些 post(按访问级别,论坛 table 中的 rank_id
是允许的最小值排名)。
我只想确认在 JOIN 部分中使用占位符(或者更确切地说,一个变量)是否有效?还是我只能使用 tables?我很确定我没有正确使用它,在这种情况下我还能如何检查用户的等级?
我也不确定我的其他 JOIN 是否有效,呸! (如果你不知道,我是 JOIN 的新手)
您 可以 在 JOIN
的 ON
子句中适当使用占位符。 ON
条件必须是一些表达式,当比较两个 table 之间的行与行时,该表达式的计算结果为 TRUE
,因此像
这样的条件
FROM
t1
LEFT JOIN t2 ON t1.id = t2.id AND t2.othercol = ?
将是 ON
中 ?
占位符的有效使用。在像上面那样的连接条件中,id
列 和 匹配 ?
输入值的 othercol
列都必须为真要满足的连接。您会在 LEFT JOIN
中看到这种用法,这时需要的不仅仅是一个列匹配来关联 table,但是添加 WHERE
条件会错误地导致 LEFT JOIN
省略 NULL
s,因此表现得像 INNER JOIN
.
然而,在你的情况下,看起来你真的只需要将该用户条件移动到 WHERE
子句中以将结果集过滤为请求的用户 ID。
SELECT {Lots of select stuff here}
FROM tab_posts tposts
INNER JOIN tab_users tusers ON tposts.user_id = tusers.id
INNER JOIN tab_ranks tranks ON tusers.rank_id = tranks.id
INNER JOIN tab_avatars tavatars ON tusers.avatar_id = tavatars.id
INNER JOIN tab_threads tthreads ON tposts.thread_id = tthreads.id
INNER JOIN tab_forums tforums ON tthreads.forum_id = tforums.id
WHERE
/* This condition belongs in the WHERE */
tusers.id = ?
tposts.thread_id = ?
AND tforums.rank_id <= tuser.rank_id
只要您的 table 确实按照联接表达它们的方式进行布局,您其余的联接看起来都是正确的。
为了进一步概括这一点,?
占位符可以用在任何您将在查询中使用标量值的地方;也就是说,字符串或数值(或布尔值、blob 等)。因此,您可以将它们用作函数参数,例如:
/* Truncate a column to some ? number of characters */
SELECT LEFT(column, ?)
或 SELECT
列表中的标量值:
/* Add an additional string suffix to every row in a column */
SELECT CONCAT(column, ?)
你 不能 使用 ?
代替 table 或列名。它们仅适用于标量值。
我有以下 SQL 查询,用于输出论坛 posts 与 posts 的关系 tables 中的相关数据(用户 post编辑它,forum/thread 它是 etc 的子项)。
我正在使用 PDO 位置占位符(因此是 ?)
SELECT {Lots of select stuff here}
FROM tab_posts tposts
INNER JOIN tab_users tuser ON tuser.id=?
INNER JOIN tab_users tusers ON tposts.user_id=tusers.id
INNER JOIN tab_ranks tranks ON tusers.rank_id=tranks.id
INNER JOIN tab_avatars tavatars ON tusers.avatar_id=tavatars.id
INNER JOIN tab_threads tthreads ON tposts.thread_id=tthreads.id
INNER JOIN tab_forums tforums ON tthreads.forum_id=tforums.id
WHERE tposts.thread_id=? AND tforums.rank_id <= tuser.rank_id
所以在这个查询中我使用了 2 个占位符,第一个是从会话中检索到的用户 ID,另一个是从请求中检索到的线程 ID(以确保我们只列出 posts 属于该线程)。
tuser
是会话用户,tusers
是提交 post 的用户的别名。我只需要 tuser
检查会话用户是否被允许查看那些 post(按访问级别,论坛 table 中的 rank_id
是允许的最小值排名)。
我只想确认在 JOIN 部分中使用占位符(或者更确切地说,一个变量)是否有效?还是我只能使用 tables?我很确定我没有正确使用它,在这种情况下我还能如何检查用户的等级?
我也不确定我的其他 JOIN 是否有效,呸! (如果你不知道,我是 JOIN 的新手)
您 可以 在 JOIN
的 ON
子句中适当使用占位符。 ON
条件必须是一些表达式,当比较两个 table 之间的行与行时,该表达式的计算结果为 TRUE
,因此像
FROM
t1
LEFT JOIN t2 ON t1.id = t2.id AND t2.othercol = ?
将是 ON
中 ?
占位符的有效使用。在像上面那样的连接条件中,id
列 和 匹配 ?
输入值的 othercol
列都必须为真要满足的连接。您会在 LEFT JOIN
中看到这种用法,这时需要的不仅仅是一个列匹配来关联 table,但是添加 WHERE
条件会错误地导致 LEFT JOIN
省略 NULL
s,因此表现得像 INNER JOIN
.
然而,在你的情况下,看起来你真的只需要将该用户条件移动到 WHERE
子句中以将结果集过滤为请求的用户 ID。
SELECT {Lots of select stuff here}
FROM tab_posts tposts
INNER JOIN tab_users tusers ON tposts.user_id = tusers.id
INNER JOIN tab_ranks tranks ON tusers.rank_id = tranks.id
INNER JOIN tab_avatars tavatars ON tusers.avatar_id = tavatars.id
INNER JOIN tab_threads tthreads ON tposts.thread_id = tthreads.id
INNER JOIN tab_forums tforums ON tthreads.forum_id = tforums.id
WHERE
/* This condition belongs in the WHERE */
tusers.id = ?
tposts.thread_id = ?
AND tforums.rank_id <= tuser.rank_id
只要您的 table 确实按照联接表达它们的方式进行布局,您其余的联接看起来都是正确的。
为了进一步概括这一点,?
占位符可以用在任何您将在查询中使用标量值的地方;也就是说,字符串或数值(或布尔值、blob 等)。因此,您可以将它们用作函数参数,例如:
/* Truncate a column to some ? number of characters */
SELECT LEFT(column, ?)
或 SELECT
列表中的标量值:
/* Add an additional string suffix to every row in a column */
SELECT CONCAT(column, ?)
你 不能 使用 ?
代替 table 或列名。它们仅适用于标量值。