【问题标题】:MySQL UNION Only Includes First TableMySQL UNION 仅包含第一个表
【发布时间】:2013-04-20 18:34:20
【问题描述】:

我需要在两个表上执行 FULL OUTER JOIN,我正在尝试使用 LEFT JOIN/RIGHT JOIN/UNION ALL 技术在 MySQL 中实现它。

以下是原始表格:

giving_totals:
+--------------+---------------+-------------+
| country_iso2 | total_given   | supersector |
+--------------+---------------+-------------+
| AE           | 1396986989.02 |           3 |
| AE           |  596757809.20 |           4 |
| AE           |  551810209.87 |           5 |
| AE           |   25898255.77 |           7 |
| AE           |      32817.63 |           9 |
...
+--------------+---------------+-------------+

receiving_totals:
 +--------------+----------------+-------------+
| country_iso2 | total_received | supersector |
+--------------+----------------+-------------+
| AE           |    34759000.00 |           3 |
| AE           |      148793.82 |           7 |
| AE           |         734.30 |           9 |
| AF           |  6594479965.85 |           1 |
| AF           |  2559712971.26 |           2 |
+--------------+----------------+-------------+

我希望结果表为每个国家/地区的每个超级部门代码都有一个条目,即使它没有为该部门提供或收款(如果有人熟悉,这来自 AidData 项目数据集。)我想完成这是通过对 LEFT JOIN(获取所有给予条目)和 RIGHT JOIN(获取所有接收条目)进行 UNION。这是我尝试过的查询:

SELECT g.country_iso2 AS country_iso2, g.total_given AS `total_given`,R.total_received AS `total_received`,g.supersector AS `supersector` 
FROM (`giving_totals` `g` 
LEFT JOIN `receiving_totals` `r` 
ON(((g.country_iso2 = r.country_iso2) 
AND (g.supersector = r.supersector)))) 

UNION ALL

SELECT g.country_iso2 AS country_iso2, g.total_given AS `total_given`,R.total_received    AS `total_received`,g.supersector AS `supersector` 
FROM (`giving_totals` `g` 
RIGHT JOIN `receiving_totals` `r` 
ON(((g.country_iso2 = r.country_iso2) 
AND (g.supersector = r.supersector)))) 

但这只会返回第一个连接,无论我是先放置右连接还是左连接。我想我可能误解了 UNION 操作,因为个人加入每个返回我所期望的。一如既往地感谢任何帮助。

【问题讨论】:

  • 在联合的第二个选择中使用您加入的表中的表别名,否则您将获得 NULL country_iso2 和 supersector。如果您不想看到同时给出和收到两次的行,请使用 UNION 而不是 UNION ALL。除此之外,查询没有任何问题。

标签: mysql left-join union right-join


【解决方案1】:

这里有另一种方法来做full outer join

SELECT driver.country_iso2 AS country_iso2,
       g.total_given AS `total_given`,
       R.total_received AS `total_received`,
       driver.supersector AS `supersector` 
from ((select distinct country_iso2, supersector
       from giving_totals
      ) union
      (select distinct country_iso2, supersector
       from receiving_totals
      )
     ) driver left outer join
     giving_totals gt
     on gt.country_iso2 = driver.country_iso2 and
        gt.supersector = driver.country_iso2 left outer join
     receiving_totals rt
     on rt.country_iso2 = driver.country_iso2 and
        rt.supersector = driver.country_iso2

也就是说,将联合作为子查询来获取您感兴趣的所有组合。然后您可以对该表执行left outer join

您的问题的原因是第二个查询中的别名。你可以试试这个:

SELECT r.country_iso2 AS country_iso2, g.total_given AS `total_given`,R.total_received    AS `total_received`,r.supersector AS `supersector` 
FROM (`giving_totals` `g` 
RIGHT JOIN `receiving_totals` `r` 
ON(((g.country_iso2 = r.country_iso2) 
AND (g.supersector = r.supersector)))) 

对于这些值,原始表单将包含 NULL。

【讨论】:

  • 使用您的第一个查询,total_given 和 total_received 字段为 NULL(我现在看到您在帖子底部提到了。)但是如何使用第二个查询来获取实际值?单独运行该查询与我的原始查询具有相同的效果。
  • @Matt 。 . .当存在不匹配时,您将获得 NULL 值。 iso/supersector 的某些值仅存在于一张表中。另一个表中的值将为 NULL。
  • 我仍在努力解决这个问题,但我不明白为什么我尝试的 UNION 不起作用。 LEFT JOIN 和 RIGHT JOIN 一起具有所有可能的组合,因此将它们放在一个表中应该将它们全部放在一起。但是 UNION 并没有发挥应有的作用。也许我不了解您的 cmets,但我仍然不明白为什么我的原始查询不起作用。
  • @Matt 。 . .你看到我的修改版join了吗?您正在进行正确的连接,因此当您选择 g.country_iso2 时,它可能为 NULL。您只需要在第二个子查询中使用正确的别名r,而不是g
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-17
  • 2016-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多