MySQL 全连接(联合)与不明确的列名

问题描述 投票:0回答:2

令我非常失望的是,这么多年之后 MySQL 仍然不支持 FULL JOIN(为什么?)并且我必须使用 UNION 作为解决方法。说我在执行以下查询时遇到问题。我有两个表作为例子:

计算机

id   userid   owner   cpu   
1    1        Jack    3.4
2    1        Jack    3.4
3    2        Sara    3.0

监视器

id   userid   owner   inch  
1    1        Jack    22    
2    1        Jack    22    
3    3        Mark    17    
4    4        Luke    32    

基本上我有一个计算机列表,其规格已分配给所有者。同样,我有一个带有规格的显示器列表,并且每个显示器都分配给一个所有者。我想将所有者的这两个表合并成这个结果:

id   userid   owner   cpu   id   userid   owner   inch  
1    1        Jack    3.4   1    1        Jack    22
2    1        Jack    3.4   2    1        Jack    22
3    2        Sara    3.0   null null     null    null 
null null     null    null  3    3        Mark    17
null null     null    null  4    4        Luke    32

我可以通过这个查询成功得到上面的结果:

SELECT * FROM computers AS a
LEFT OUTER JOIN monitors AS o on a.owner = o.owner
UNION
SELECT * FROM computers AS a
RIGHT OUTER JOIN monitors AS o on a.owner = o.owner

问题是:

  1. 不想在我的查询中使用快乐字符,不仅因为它效率不高,而且因为我只需要一些特定的列而不是全部
  2. 两个表都有不明确的列名(id、userid、所有者),因此,例如,我似乎无法按所有者排序。我知道我应该使用别名,但我不明白如何实现它
  3. 我必须使用 WHERE 语句,但由于列名不明确,我再次不明白如何实现它

现在总结我在伪查询中所说的内容:

选择 id AS a_id、用户 ID AS a_userid、所有者 AS a_owner 但不是 cpu 来自 cpu = 3.4 的计算机

所有者联合和加入:

从监视器中选择 id AS b_id、用户 ID AS b_userid、所有者 AS b_owner、英寸 AS b_inch,其中英寸 = 22

感谢您的宝贵时间。

mysql sql select join union
2个回答
0
投票

模拟

full outer join
的另一种方法是使用子查询获取完整的值列表(在您的情况下为
owner
)。然后使用
left outer join
引入其他值。根据您的描述:

select c.id as c_id, c.userid as c_userid, o.owner as owner,
       m.id as m_id, m.user_id as m_userid, m.inch
from (select owner from computers union
      select owner from monitors
     ) o left outer join
     computers c
     on o.owner = c.owner left outer join
     monitors m
     on o.owner = m.owner;

但是,您提到的查询不会生成这些结果。它将生成“Jack”的四个结果。

编辑:

我怀疑您想匹配

owner
id
user_id
:

select c.id as c_id, c.userid as c_userid, o.owner as owner,
       m.id as m_id, m.user_id as m_userid, m.inch
from (select owner, id, userid from computers union
      select owner, id, userid from monitors
     ) o left outer join
     computers c
     on o.owner = c.owner and o.userid = c.userid and o.id = c.id left outer join
     monitors m
     on o.owner = m.owner and o.userid = m.userid and o.id = m.id;

0
投票

这是 cpu = 3.4 且英寸 = 22 上的完整外连接。首先获取所有计算机并连接显示器,然后获取所有显示器并连接计算机。主表条件在 WHERE 子句中,外连接条件在 ON 子句中。

SELECT 
    a.userid, a.owner, a.id as computer_id, o.id as monitor_id, o.inch
FROM  
    computers AS a
LEFT OUTER JOIN 
    monitors AS o ON a.owner = o.owner 
                  AND a.userid = o.userid 
                  AND o.inch = 22
WHERE 
    a.cpu = 3.4

UNION

SELECT 
    o.userid, o.owner, a.id as computer_id, o.id as monitor_id, o.inch
FROM 
    monitors AS o
LEFT OUTER JOIN 
    computers AS a ON a.owner = o.owner 
                   AND a.userid = o.userid 
                   AND a.cpu = 3.4
WHERE 
    o.inch = 22;

但是,可以通过仅添加第一个选择未找到的记录(即没有匹配计算机的监视器)来加快速度。然后您可以使用 UNION ALL 代替 UNION,这可以为 dbms 节省大量工作。您只需选取外部连接表的一个不可为空的列。当它为 NULL 时,则该记录是外连接的。

SELECT a.userid, a.owner, a.id as computer_id, o.id as monitor_id, o.inch
FROM computers AS a
LEFT OUTER JOIN monitors AS o 
  ON a.owner = o.owner and a.userid = o.userid and o.inch = 22
WHERE a.cpu = 3.4
UNION ALL
SELECT o.userid, o.owner, a.id as computer_id, o.id as monitor_id, o.inch
FROM monitors AS o
LEFT OUTER JOIN computers AS a
  ON a.owner = o.owner and a.userid = o.userid and a.cpu = 3.4
WHERE o.inch = 22 and o.owner is null;
© www.soinside.com 2019 - 2024. All rights reserved.