我有以下SQL查询,用于输出论坛帖子,其中包含关系表中的帖子相关数据(发布它的用户,论坛/帖子,它是孩子等)。
我正在使用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(以确保我们只列出属于该线程的帖子) )。
tuser
是会话用户,tusers
是提交帖子的用户的别名。我只需要tuser
来检查是否允许会话用户查看这些帖子(按访问等级,论坛表中的rank_id
是允许的最低等级。)
我想确认在JOIN部分使用占位符(或者更确切地说,一个变量)是否有效?或者我只限于使用桌子?我很确定我使用的不正确,在这种情况下我还能检查用户的等级吗?
我也不确定我的其他JOIN实际上是否有效,哇! (如果你不知道,我是新手使用JOIN)
答案 0 :(得分:2)
可以1}} JOIN
ON
子句中的占位符。 ON
条件只需要是一个表达式,当两个表之间的行与行进行比较时,它会计算为TRUE
,所以像
FROM
t1
LEFT JOIN t2 ON t1.id = t2.id AND t2.othercol = ?
将有效使用?
中的ON
占位符。在上述连接条件下,id
列和匹配othercol
输入值的?
列的匹配对于连接而言必须为true得到满足。当LEFT JOIN
s中不仅需要列匹配来表示这些表时,您通常会在WHERE
中看到此用法,但添加LEFT JOIN
条件会导致NULL
忽略{{ 1}} 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
您的剩余联接看起来是正确的,只要您的表格实际按照联接表达方式进行布局。
为了进一步概括,?
占位符可用于您在查询中使用标量值的任何位置;也就是说,字符串或数值(或布尔值,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, ?)
但不能使用?
代替表名或列名。它们只适用于标量值。