如何有效地M:N连接3个表
我有几张表:
应用程序:
id | name | url_key
===================
1 | Hello World | hello-world
2 | Snake 2 | snake-2
开发人员:
id | name | url_key
===================
1 | Mr. Robinson | mr-robinson
2 | Richard | richard
3 | Nokia | nokia
应用程序开发人员分配
app_id | developer_id
=====================
1 | 1
1 | 2
2 | 3
因此,正如您所见,一个应用程序可能有多个开发人员。
我真正需要的是编写一个 PostgreSQL 查询来选择所有具有相关开发人员有用信息的应用程序。 例如:
Hello World | 1-hello-world | Mr.Robinson<1-mr-robinson> /and 1 more/
Snake 2 | 2-snake-2 | Nokia<3-nokia>
如果应用程序有一个开发人员,只需将开发人员的名称、url key 和 id 附加到应用程序中,如果有更多开发人员,则附加第一个并附加“有多少开发人员”的信息。
最重要的是 - 我需要最终过滤结果(例如,不返回某些指定开发人员的应用程序)。
我知道可以通过为应用程序本身编写第一个查询然后为每行发送下一个查询来解决这个问题,但我认为这不是一个好的方法...
如果我只是简单地加入表:
SELECT * FROM apps a
LEFT JOIN apps_developers_assignment ada ON a.id = ada.app_id
LEFT JOIN developers d ON ada.developer_id = d.id
Hello World | 1-hello-world | Mr.Robinson<1-mr-robinson>
Hello World | 1-hello-world | Richard<2-richard>
Snake 2 | 2-snake-2 | Nokia<3-nokia>
它会返回重复的应用程序...并且我不知道开发人员如何过滤这些结果(正如我上面写的)。
I have few tables:
Apps:
id | name | url_key
===================
1 | Hello World | hello-world
2 | Snake 2 | snake-2
Developers:
id | name | url_key
===================
1 | Mr. Robinson | mr-robinson
2 | Richard | richard
3 | Nokia | nokia
Apps-Developers-Assignment
app_id | developer_id
=====================
1 | 1
1 | 2
2 | 3
So as you may see, one app may have more than one developer.
What i actually need is to write a PostgreSQL query to select all apps with some usefull information about related developers.
e.g. sth like this:
Hello World | 1-hello-world | Mr.Robinson<1-mr-robinson> /and 1 more/
Snake 2 | 2-snake-2 | Nokia<3-nokia>
So if the app has one developer, just append the developer's name, url key and id to the app, if it has more developers, append the first and append the information of "how many developers are there".
And what's most important - i need to eventually filter the results (e.g. not return apps from some specified developer).
I know it can be solved by write first query for apps itself and then send next query per each row, but not the nice way, i think...
If i just simply JOIN the table:
SELECT * FROM apps a
LEFT JOIN apps_developers_assignment ada ON a.id = ada.app_id
LEFT JOIN developers d ON ada.developer_id = d.id
Hello World | 1-hello-world | Mr.Robinson<1-mr-robinson>
Hello World | 1-hello-world | Richard<2-richard>
Snake 2 | 2-snake-2 | Nokia<3-nokia>
It returns duplicate apps... and i don't know how to filter these results by developer (as i wrote above).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
假设您只想过滤掉一名开发人员,则需要传递一个参数。为此,我将此参数/变量称为 @excludeDevId。
我对 T-SQL 更熟悉,因此这可能/也需要 Postgres 中的等效语法。另外,由于左连接为空,我将保留空值 - 从您的输出中,您可能想要合并(可能还有其他一些输出调整)。这是即兴的且未经测试的,但至少应该足以让您朝着正确的方向前进:
Assuming you only want to filter out one developer, you will need to pass a parameter. I am calling this parameter/variable @excludeDevId for this purpose.
I am much more familiar to T-SQL, so this may/will also need the equivalent syntax in Postgres. Also, I am leaving nulls as a result of the left join as null--from your output you probably want to COALESCE (probably some other output tweaks as well). This is off the cuff and untested, but should be enough to get you moving in the right direction at least:
如果您想使用左连接,则需要将条件放在连接上,否则它将创建一个内部连接,并且不会返回包含 null 的行...尝试如下操作:
If you want to use a left join, you'll need to put your condition on the join, otherwise it'll crate an inner join and the rows that have null in won't get returned... try something like this: