如何进行多对多表外连接?
我有 3 个表:foo、foo2bar 和 bar。 foo2bar 是 foo 和 bar 之间的多对多映射。 以下是内容。
select * from foo
+------+
| fid |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
+------+
select * from foo2bar
+------+------+
| fid | bid |
+------+------+
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 2 | 3 |
| 4 | 4 |
+------+------+
select * from bar
+------+-------+------+
| bid | value | zid |
+------+-------+------+
| 1 | 2 | 10 |
| 2 | 4 | 20 |
| 3 | 8 | 30 |
| 4 | 42 | 30 |
+------+-------+------+
我想要请求的是,“给我一个 zid 为 30 的所有 fid 和值的列表”
我希望得到所有 fid 的答案,因此结果如下所示:
+------+--------+
| fid | value |
+------+--------+
| 1 | null |
| 2 | 8 |
| 3 | null |
| 4 | 42 |
+------+--------+
I have 3 tables, foo, foo2bar, and bar. foo2bar is a many to many map between foo and bar. Here are the contents.
select * from foo
+------+
| fid |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
+------+
select * from foo2bar
+------+------+
| fid | bid |
+------+------+
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 2 | 3 |
| 4 | 4 |
+------+------+
select * from bar
+------+-------+------+
| bid | value | zid |
+------+-------+------+
| 1 | 2 | 10 |
| 2 | 4 | 20 |
| 3 | 8 | 30 |
| 4 | 42 | 30 |
+------+-------+------+
What I want to request is, "Give me a list of all the fid and values with zid of 30"
I expect an answer for all the fids, so the result would look like:
+------+--------+
| fid | value |
+------+--------+
| 1 | null |
| 2 | 8 |
| 3 | null |
| 4 | 42 |
+------+--------+
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在 MySQL 5.0.51 上测试。
这不是子查询,它只是使用括号来指定连接的优先级。
Tested on MySQL 5.0.51.
This is not a subquery, it just uses parentheses to specify the precedence of joins.
未经测试的
untested
如果您没有返回 fid = 3 的行,那么您的服务器已损坏。
此代码应该执行我认为您想要的操作:
请记住,如果 fid 与 zid 为 30 的两个柱相关,则可以返回 fid 的两个值。
If you're not getting back a row for fid = 3 then your server is broken.
This code should do what I think you want:
Keep in mind that it is possible to get back two values for a fid if it is related to two bars with a zid of 30.
弄清楚后,您就可以从您的选择开始。 不要包含您最终不想看到的列。
然后我们可以做WHERE子句,可以看到正如你所表达的那样。
现在,棘手的部分是使用 LEFT JOIN 将 FROM 子句的事物连接在一起,因为我们希望查看每个 fid,无论是否存在中间匹配:
Working it out, you can start with your select. Don't include columns you don't want to ultimately see.
Then we can do the WHERE clause, which can see is just as you expressed it.
Now the tricky part to connect things together for our FROM clause, using LEFT JOINs because we want to see every fid, whether or not there are intermediate matches:
FWIW,问题实际上并不是关于多对多:这可以很简单地作为一个联合来完成。
SQL 中真正的多对多是 CROSS JOIN
FWIW, the question isn't really about a many-to-many: this could quite simply be done as a union.
A real many-to-many in SQL is a CROSS JOIN