MySQL通过关系表加入

时间:2013-10-22 16:01:48

标签: php mysql

您好我似乎无法找到正确的方法来编写此查询。我有两个实体网站和客户端,以及一个通过其id字段关联它们的表。

这是一对多关系。即一个网站可以有多个客户,一个客户可以有多个网站。

我正在尝试编写一个返回所有具有属于它们的客户端的网站的查询。我想返回所有网站,即使他们没有与他们相关的客户。以下是我目前正在处理的查询:

这三个表是ost_sites =网站,ost_site_auth =关系表,ost_clients =客户

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

site_id |    name    | site_url
1          facebook    facebook.com
2          twitter     twitter.com
3          tubmblr     tumblr.com
4          google      google.com

ost_site_auth

(在auth列表中注意没有site_id = 3)

id |   site_id    | client_id
1        1             1
2        1             2
3        2             1 
4        2             2
5        4             1
6        4             4

ost_client

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

2 个答案:

答案 0 :(得分:2)

您的加入看起来有点偏......试试这个

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表开始,我们想要所有结果,无论其他表中是否匹配。
  • 然后,我们对表left outer join进行了ost_site_auth。这意味着如果ost_site_auth中的某些内容与ost_sites中的某些内容不匹配,则不会返回该内容。但是,由于ost_sites部分,ost_site_auth中与left outer中的内容不匹配的内容将被返回。
  • 接下来,我们重复left outer join的{​​{1}}。


不确定你想要什么......让我们假设我们在表格中列出了这些数据:

  • 网站#1没有客户
  • 网站#2有一个客户端:A
  • 网站#3有两个客户端:B,C
  • 网站#4有三个客户端:D,E,F
  • 网站#5没有客户
  • 客户G和H没有关联网站

查询一个

ost_clients

那将返回(基本上)

      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

查询二

SITE     CLIENT 
1        NULL
2        A
3        B
3        C
4        D
4        E
4        F
5        NULL

那将返回(基本上)

      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

查询三

SITE     CLIENT  
2        A
3        B
3        C
4        D
4        E
4        F 

那将返回(基本上)

      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

查询四

SITE     CLIENT  
1        NULL
2        A
3        B
3        C
4        D
4        E
4        F
5        NULL
NULL     G
NULL     H 

那将返回(基本上)

      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 

查询五

SITE         
2
3
4 

那将返回(基本上)

      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 

查询五

SITE        CLIENT_COUNT  
2           1
3           2
4           3

那将返回(基本上)

      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 

答案 1 :(得分:0)

结帐

Full Outer Join in MySQL

我认为你真正需要做的就是做一个与右外连接相同的查询并将它们联合起来。