我正在选择数据来输出用户已标记书籍的帖子。
用于保存用户id
的{{1}}的主表具有bookMarked,称为posts
。这是基于bookMarks
从posts
表中选择,以显示给用户的表格。
书签
posts
帖子
id | postId | userId
--------------------------
1 | US01 | 1
2 | US02 | 1
3 | US01 | 2
4 | US02 | 2
我的sql目前是这样的:
id | postId | postTitle
--------------------------
1 | US01 | Title 1
2 | US02 | Title 2
3 | US03 | Title 3
4 | US04 | Title 4
注意,我将表select a.postsTitle
from posts a
inner join bookmarks b
on b.userId = a.userId
and b.userId = :userId
放在表posts
之前。但是,因为我根据bookmarks
中的内容进行选择,是否有必要在sql语句中首先声明表bookmarks
而不是bookmarks
?我会这样做会导致数据选择或效率问题吗?
或者我应该这样做:
post
注意,我先把表select b.postsTitle
from bookmarks a
inner join posts b
on a.userId = b.userId
and a.userId = :userId
放在这里。
答案 0 :(得分:4)
而不是以下内容:
select a.postsTitle
from posts a
inner join bookmarks b
on b.userId = a.userId
and b.userId = :userId
您应该考虑使用WHERE
子句以及正确的大小写格式化这种格式的JOIN:
SELECT p.postsTitle
FROM bookmarks b
INNER JOIN posts p
ON p.userId = b.userId
WHERE b.userId = :userId
虽然对MySQL没有任何区别(性能明智),但是你把这些表放在INNER JOIN
中(MySQL将它们视为相同并且将以相同的方式优化它们),它的惯例是您首先应用WHERE
子句的表。事实上,假设正确的索引,MySQL很可能从具有WHERE
子句的表开始,因为它缩小了结果集,而MySQL喜欢从具有最少行的集合开始。
将连接表的列放在ON子句的第一位也是惯例。它只是更符合逻辑。在您使用它时,请使用逻辑表别名。
唯一需要注意的是,如果您没有为列命名,请使用SELECT *
,如下所示:
SELECT *
FROM bookmarks b
INNER JOIN posts p
ON p.userId = b.userId
WHERE b.userId = :userId
您将按照查询中列出的顺序获取列。在这种情况下,您将获得bookmarks
的列,然后是posts
的列。
大多数人会说在生产查询中永远不要使用SELECT *
,但如果您确实必须返回所有列,并且首先需要posts
中的列,则可以执行以下操作:
SELECT p.*, b.*
FROM bookmarks b
INNER JOIN posts p
ON p.userId = b.userId
WHERE b.userId = :userId
明确返回结果集总是好的。
答案 1 :(得分:1)
如果使用 INNER JOIN ,则在JOIN子句的任一侧放置表时查询性能或最终结果集没有影响。
观察到的唯一差异是按照返回的列顺序,只有 SELECT *
时才。假设你有tableA(aid,col1,col2)和tableB(bid,col3)
SELECT *
FROM tableA
INNER JOIN tableB
ON tableA.aid=tableB.bid
按顺序返回列
aid|col1|col2|bid|col3
另一方面
SELECT *
FROM tableB
INNER JOIN tableA
ON tableA.aid=tableB.bid
按顺序返回列
bid|col3|aid|col1|col2|
但在 LEFT JOIN 或 RIGHT JOIN 的情况下,这很重要。