Database 如何有效地连接3个表M:N
我有几张桌子: 应用程序:Database 如何有效地连接3个表M:N,database,postgresql,Database,Postgresql,我有几张桌子: 应用程序: 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 开发者: id | name | url_key =
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
开发者:
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查询,以选择所有包含相关开发人员有用信息的应用程序。
e、 像这样的东西:
Hello World | 1-hello-world | Mr.Robinson<1-mr-robinson> /and 1 more/
Snake 2 | 2-snake-2 | Nokia<3-nokia>
SELECT * FROM apps a
LEFT JOIN apps_developers_assignment ada ON a.id = ada.app_id
AND ada.developerid = :devid
LEFT JOIN developers d ON ada.developer_id = d.id
WHERE a.id = :appid
Hello World | 1-Hello-World | Robinson先生/还有1个/
Snake 2 | 2-Snake-2 |诺基亚
因此,如果应用程序有一个开发人员,只需将开发人员的姓名、url键和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>
从应用程序a中选择*
左加入apps\u开发者\u分配ada ON a.id=ada.app\u id
在ada.developer\u id=d.id上左键连接开发人员d
你好,世界1-你好,世界罗宾逊先生
你好世界| 1-你好世界|理查德
Snake 2 | 2-Snake-2 |诺基亚
它返回重复的应用程序。。。我不知道如何按开发人员筛选这些结果(如我上面所写)。如果您想使用左联接,您需要将您的条件放在联接上,否则它将装箱一个内部联接,并且不会返回包含null的行。。。试着这样做:
Hello World | 1-hello-world | Mr.Robinson<1-mr-robinson> /and 1 more/
Snake 2 | 2-snake-2 | Nokia<3-nokia>
SELECT * FROM apps a
LEFT JOIN apps_developers_assignment ada ON a.id = ada.app_id
AND ada.developerid = :devid
LEFT JOIN developers d ON ada.developer_id = d.id
WHERE a.id = :appid
如果要使用左联接,需要将条件放在联接上,否则它将装入一个内部联接,并且将不会返回中为null的行。。。试着这样做:
Hello World | 1-hello-world | Mr.Robinson<1-mr-robinson> /and 1 more/
Snake 2 | 2-snake-2 | Nokia<3-nokia>
SELECT * FROM apps a
LEFT JOIN apps_developers_assignment ada ON a.id = ada.app_id
AND ada.developerid = :devid
LEFT JOIN developers d ON ada.developer_id = d.id
WHERE a.id = :appid
假设您只想筛选出一个开发人员,则需要传递一个参数。为此,我将此参数/变量称为@excludeDevId 我对T-SQL更为熟悉,因此这可能/也将需要Postgres中的等效语法。此外,由于左连接,我将null保留为null——从您的输出中,您可能希望合并(可能还有其他一些输出调整)。这是即兴的、未经测试的,但至少应该足以让你朝着正确的方向前进:
SELECT
a.name AppName,
a.id AppId,
d.id DevId,
d.url_key Url,
d.name DevName,
CAST(agg.dev_count - 1 as VARCHAR) + ' more'
FROM
(
SELECT
MAX(ada.developer_id) first_dev_id,
COUNT(ada.developer_id) dev_count,
app_id
FROM
apps_developers_assignment ada
WHERE
d.id != @excludeDevId
GROUP BY
app_id
) agg
INNER JOIN apps a ON a.id = agg.app_id
LEFT JOIN developers d ON agg.developer_id = d.id
假设您只想筛选出一个开发人员,则需要传递一个参数。为此,我将此参数/变量称为@excludeDevId 我对T-SQL更为熟悉,因此这可能/也将需要Postgres中的等效语法。此外,由于左连接,我将null保留为null——从您的输出中,您可能希望合并(可能还有其他一些输出调整)。这是即兴的、未经测试的,但至少应该足以让你朝着正确的方向前进:
SELECT
a.name AppName,
a.id AppId,
d.id DevId,
d.url_key Url,
d.name DevName,
CAST(agg.dev_count - 1 as VARCHAR) + ' more'
FROM
(
SELECT
MAX(ada.developer_id) first_dev_id,
COUNT(ada.developer_id) dev_count,
app_id
FROM
apps_developers_assignment ada
WHERE
d.id != @excludeDevId
GROUP BY
app_id
) agg
INNER JOIN apps a ON a.id = agg.app_id
LEFT JOIN developers d ON agg.developer_id = d.id
你被困在哪里?你有什么问题吗?@Oded我已经修改了这个问题,我希望现在更清楚了,你被困在哪里了?你有什么问题?@Oded我已经修改了这个问题,我希望现在问题更清楚了,如果你不想返回空值,请将联接设置为“内部联接”,并将条件放在WHERE子句中。如果你不想返回空值,请将联接设置为“内部联接”,并将条件放在WHERE子句中。