Php MySQL通过关系表连接
嗨,我似乎找不到写这个查询的正确方法。我有两个实体网站和客户端,以及一个通过id字段将它们关联起来的表 这是一种多对多的关系。i、 一个网站可以有多个客户端,一个客户端可以有多个网站 我试图写一个查询,返回所有的网站与客户属于他们。我想返回所有的网站,即使他们没有与他们相关联的客户端。以下是我目前正在处理的问题: 这三个表是ost_站点=网站,ost_站点_授权=关系表,ost_客户端=客户端Php MySQL通过关系表连接,php,mysql,Php,Mysql,嗨,我似乎找不到写这个查询的正确方法。我有两个实体网站和客户端,以及一个通过id字段将它们关联起来的表 这是一种多对多的关系。i、 一个网站可以有多个客户端,一个客户端可以有多个网站 我试图写一个查询,返回所有的网站与客户属于他们。我想返回所有的网站,即使他们没有与他们相关联的客户端。以下是我目前正在处理的问题: 这三个表是ost_站点=网站,ost_站点_授权=关系表,ost_客户端=客户端 SELECT ost_sites.site_id, ost_sites.name,
SELECT
ost_sites.site_id,
ost_sites.name,
ost_sites.site_url,
ost_site_auth.site_id,
ost_site_auth.client_id
ost_clients.client_id,
CONCAT_WS(" ", ost_clients.lastname, ost_clients.firstname) as name,
FROM ost_sites
LEFT JOIN (ost_site_auth, ost_clients)
ON (ost_sites.site_id=ost_site_auth.site_id
AND ost_site_auth.client_id=ost_clients.client_id)
GROUP BY ost_sites.name
我得到一个结果集,但它不会返回所有站点,而且所有行都没有与它们关联的客户端
非常感谢你的帮助
编辑:
以下是表的列:
ost_站点
site_id | name | site_url
1 facebook facebook.com
2 twitter twitter.com
3 tubmblr tumblr.com
4 google google.com
ost_站点_授权
(注意认证列表中没有站点id=3)
ost_客户端
client_id | firstname | lastname
1 wilma flintstone
2 bam bam
3 fred flintstone
4 barney rubble
预期产出:
site_id | name | site_url | client_name |
1 facebook facebook.com wilma flintstone
1 facebook facebook.com bam bam
2 twitter twitter.com wilma flintstone
2 twitter twitter.com bam bam
4 google google.com wilma flintstone
4 google google.com barney rubble
3 tumblr tumlr.com NULL
你的加入看起来有点不对劲。。。试试这个
SELECT
ost_sites.site_id,
ost_sites.name,
ost_sites.site_url,
ost_site_auth.site_id,
ost_site_auth.client_id
ost_clients.client_id,
CONCAT_WS(" ", ost_clients.lastname, ost_clients.firstname) as name
FROM ost_sites
LEFT OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
LEFT OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.name
让我试着给你解释一下
- 我们从
表开始,不管其他表中是否有匹配的内容,我们都希望从中获得所有结果李>ost_sites
- 然后,我们对表
执行ost\u site\u auth
左外部联接。这意味着,如果来自
的内容与ost_site_auth
中的内容不匹配,则不会返回该内容。但是,ost_sites
中与ost_站点
中的内容不匹配的内容将被返回,因为ost_站点_auth
部分李>位于左侧外部
- 接下来,我们为
重复ost_客户机
左外连接
- 接下来,我们为
不知道你想要什么。。。让我们假设这些数据在表中表示:
- 站点1没有客户端
- 站点2有一个客户端:A
- 站点3有两个客户端:B、C
- 站点4有三个客户端:D、E、F
- 站点#5没有客户端
- 客户端G和H没有关联的站点
SELECT
ost_sites.site_id as SITE,
ost_clients.client_id as CLIENT
FROM ost_sites
LEFT OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
LEFT OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id, ost_clients.client_id
这将返回(基本上)
查询两个
SELECT
ost_sites.site_id as SITE,
ost_clients.client_id as CLIENT
FROM ost_sites
JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id, ost_clients.client_id
SELECT
ost_sites.site_id as SITE,
ost_clients.client_id as CLIENT
FROM ost_sites
FULL OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
FULL OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id, ost_clients.client_id
SELECT DISTINCT ost_sites.site_id as SITE
FROM ost_sites
LEFT OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
LEFT OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id
ORDER BY ost_sites.site_id
SELECT
ost_sites.site_id as SITE,
count(ost_clients.client_id) as CLIENT_COUNT
FROM ost_sites
JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
GROUP BY ost_sites.site_id
ORDER BY ost_sites.site_id
SELECT
ost_sites.site_id as SITE,
count(ost_clients.client_id) as CLIENT_COUNT
FROM ost_sites
LEFT OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
LEFT OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
GROUP BY ost_sites.site_id
ORDER BY ost_sites.site_id
这将返回(基本上)
查询三个
SELECT
ost_sites.site_id as SITE,
ost_clients.client_id as CLIENT
FROM ost_sites
JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id, ost_clients.client_id
SELECT
ost_sites.site_id as SITE,
ost_clients.client_id as CLIENT
FROM ost_sites
FULL OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
FULL OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id, ost_clients.client_id
SELECT DISTINCT ost_sites.site_id as SITE
FROM ost_sites
LEFT OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
LEFT OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id
ORDER BY ost_sites.site_id
SELECT
ost_sites.site_id as SITE,
count(ost_clients.client_id) as CLIENT_COUNT
FROM ost_sites
JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
GROUP BY ost_sites.site_id
ORDER BY ost_sites.site_id
SELECT
ost_sites.site_id as SITE,
count(ost_clients.client_id) as CLIENT_COUNT
FROM ost_sites
LEFT OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
LEFT OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
GROUP BY ost_sites.site_id
ORDER BY ost_sites.site_id
这将返回(基本上)
查询四个
SELECT
ost_sites.site_id as SITE,
ost_clients.client_id as CLIENT
FROM ost_sites
JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id, ost_clients.client_id
SELECT
ost_sites.site_id as SITE,
ost_clients.client_id as CLIENT
FROM ost_sites
FULL OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
FULL OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id, ost_clients.client_id
SELECT DISTINCT ost_sites.site_id as SITE
FROM ost_sites
LEFT OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
LEFT OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id
ORDER BY ost_sites.site_id
SELECT
ost_sites.site_id as SITE,
count(ost_clients.client_id) as CLIENT_COUNT
FROM ost_sites
JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
GROUP BY ost_sites.site_id
ORDER BY ost_sites.site_id
SELECT
ost_sites.site_id as SITE,
count(ost_clients.client_id) as CLIENT_COUNT
FROM ost_sites
LEFT OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
LEFT OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
GROUP BY ost_sites.site_id
ORDER BY ost_sites.site_id
这将返回(基本上)
查询五个
SELECT
ost_sites.site_id as SITE,
ost_clients.client_id as CLIENT
FROM ost_sites
JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id, ost_clients.client_id
SELECT
ost_sites.site_id as SITE,
ost_clients.client_id as CLIENT
FROM ost_sites
FULL OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
FULL OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id, ost_clients.client_id
SELECT DISTINCT ost_sites.site_id as SITE
FROM ost_sites
LEFT OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
LEFT OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id
ORDER BY ost_sites.site_id
SELECT
ost_sites.site_id as SITE,
count(ost_clients.client_id) as CLIENT_COUNT
FROM ost_sites
JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
GROUP BY ost_sites.site_id
ORDER BY ost_sites.site_id
SELECT
ost_sites.site_id as SITE,
count(ost_clients.client_id) as CLIENT_COUNT
FROM ost_sites
LEFT OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
LEFT OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
GROUP BY ost_sites.site_id
ORDER BY ost_sites.site_id
这将返回(基本上)
查询五个
SELECT
ost_sites.site_id as SITE,
ost_clients.client_id as CLIENT
FROM ost_sites
JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id, ost_clients.client_id
SELECT
ost_sites.site_id as SITE,
ost_clients.client_id as CLIENT
FROM ost_sites
FULL OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
FULL OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id, ost_clients.client_id
SELECT DISTINCT ost_sites.site_id as SITE
FROM ost_sites
LEFT OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
LEFT OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
ORDER BY ost_sites.site_id
ORDER BY ost_sites.site_id
SELECT
ost_sites.site_id as SITE,
count(ost_clients.client_id) as CLIENT_COUNT
FROM ost_sites
JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
GROUP BY ost_sites.site_id
ORDER BY ost_sites.site_id
SELECT
ost_sites.site_id as SITE,
count(ost_clients.client_id) as CLIENT_COUNT
FROM ost_sites
LEFT OUTER JOIN ost_site_auth
ON ost_sites.site_id=ost_site_auth.site_id
LEFT OUTER JOIN ost_clients
ON ost_site_auth.client_id=ost_clients.client_id
GROUP BY ost_sites.site_id
ORDER BY ost_sites.site_id
这将返回(基本上)
退房
我认为您真正需要做的就是执行与右外部联接相同的查询,并将它们联合起来。此查询得到什么结果?你能发布一个输出示例吗?或者你的一部分数据?我会用一般数据编辑帖子,但我不能输入具体数据,因为名字和网站与我的工作有关。好的。。。这里有四个问题:我刚刚编辑了这篇文章,让我知道这是否有点清楚,我甚至在这个链接的顶部添加了第五个问题…-->从你的例子来看。。。您只需要使用一个
左外部联接
。我不确定我最初建议的第一个查询如何不符合您的要求…?在第二个加入时,我意外地离开了和,而不是将其更改为。。。现在已经更新/编辑了。这可以工作并为我提供所有网站和一个与该网站关联的客户端(如果该网站没有客户端,则为空)。我只需要它返回多行,如果该网站有多个客户端。也许我可以让query返回所有有客户端的网站,然后再执行另一个查询,找出哪些网站没有客户端?这就是你想要的吗?如果直接执行联接
,它将只返回在所有三个表中都有匹配行的内容。如果您要执行一个右外部联接
,它将以反向联接顺序进行,因此您将获得所有客户端,无论它们是否在ost\u site\u auth
中有行,然后是ost\u sites
。(最好使用左外部联接
,因为它更常见,因此更容易可视化/理解。)如果要返回所有匹配的内容,即使不匹配,也应该使用另一个答案所指的完全外部联接
。。。在数据匹配的地方,您将得到一整行。但是你也会得到没有客户端和客户端的站点。没有站点。所以你不想看到没有任何客户端的站点?