And*_*w M 9 mysql join left-join
我的MySQL数据库中有两个表,一个是数据库中所有书籍的库,另一个是包含对应于用户库中书籍的各个行.
例如:
图书馆表
`id` `title`...
===== ===========
1 Moby Dick
2 Harry Potter
Run Code Online (Sandbox Code Playgroud)
收集表
`id` `user` `book`
===== ====== =======
1 1 2
2 2 2
3 1 1
Run Code Online (Sandbox Code Playgroud)
我想要做的是运行一个查询,显示所有不在用户集合中的书籍.我可以运行此查询来显示不在任何用户集合中的所有书籍:
SELECT *
FROM `library`
LEFT OUTER JOIN `collection` ON `library`.`id` = `collection`.`book`
WHERE `collection`.`book` IS NULL
Run Code Online (Sandbox Code Playgroud)
据我所知,这很好用.在PHPMyAdmin中运行此操作将导致所有不在集合表中的书籍.
但是,如何将其限制为某个用户?例如,使用上面的虚拟数据,如果用户2运行查询,我想要书1,如果用户运行查询,则不需要书1.
只是添加一个AND user=[id]不起作用,并且由于我对JOIN语句的知识非常有限,我实际上并没有得到任何结论.
此外,返回的结果的ID(显示的查询,不执行我想要但功能正常)是0 - 如何确保返回的ID是library.id?
Zan*_*ien 13
您必须将您的LEFT JOIN选择范围缩小到只有特定用户拥有的书籍,然后NULL连接表格中的任何内容都将是用户在其收藏中没有的行(书籍):
SELECT
a.id,
a.title
FROM
library a
LEFT JOIN
(
SELECT book
FROM collection
WHERE user = <userid>
) b ON a.id = b.book
WHERE
b.book IS NULL
Run Code Online (Sandbox Code Playgroud)
另一种选择是:
SELECT
a.id,
a.title
FROM
library a
WHERE
a.id NOT IN
(
SELECT book
FROM collection
WHERE user = <userid>
)
Run Code Online (Sandbox Code Playgroud)
但是,第一个解决方案更为优化,因为MySQL将为NOT IN每一行执行一次子查询,而不是仅对整个查询执行一次.直观地说,你会期望MySQL一次执行子查询并将其用作列表,但MySQL并不够聪明,无法区分相关子查询和非相关子查询.
如前所述这里:
"问题在于,对于使用IN子查询的语句,优化器会将其重写为相关子查询."
| 归档时间: |
|
| 查看次数: |
14638 次 |
| 最近记录: |