是否可以在JOIN中使用占位符?

时间:2015-01-30 00:34:51

标签: php mysql sql join pdo

我有以下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)

1 个答案:

答案 0 :(得分:2)

可以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, ?)

不能使用?代替表名或列名。它们只适用于标量值。

相关问题