如何并排比较两个 mysql 表

How to compare two mysql tables side by side

我有两个 mysql table 结构相同。我需要做的是比较两个 table 的内容。那里有很多答案如何显示出现在一个 table 而不是另一个中的行,但我需要的有点不同。我需要输出一个 table,其中每一行都包含两个 table 的列。如果在一个 table 中找不到匹配项,则列需要包含 NULL。

尽管 id 是主键,但两个 table 之间的 id 将不同。因此,例如,假设我有以下两个 tables.

Table 1

+----+---------+------------+---------+-----------+
| id | alias   | short_name | country | role      |
+----+---------+------------+---------+-----------+
| 1  | alias_1 | Product 1  | USA     | retail    |
+----+---------+------------+---------+-----------+
| 2  | alias_1 | Product 1  | USA     | corporate |
+----+---------+------------+---------+-----------+
| 3  | alias_1 | Product 1  | POL     | retail    |
+----+---------+------------+---------+-----------+
| 4  | alias_1 | Product 1  | BEL     | corporate |
+----+---------+------------+---------+-----------+
| 5  | alias_2 | Product 2  | USA     | retail    |
+----+---------+------------+---------+-----------+
| 6  | alias_2 | Product 2  | BEL     | corporate |
+----+---------+------------+---------+-----------+
| 7  | alias_2 | Product 2  | BEL     | retail    |
+----+---------+------------+---------+-----------+

Table 2

+----+---------+------------+---------+-----------+
| id | alias   | short_name | country | role      |
+----+---------+------------+---------+-----------+
| 10 | alias_1 | Product 1  | USA     | retail    |
+----+---------+------------+---------+-----------+
| 13 | alias_1 | Product 1  | USA     | corporate |
+----+---------+------------+---------+-----------+
| 14 | alias_1 | Product 1  | POL     | corporate |
+----+---------+------------+---------+-----------+
| 16 | alias_1 | Product 1  | BEL     | retail    |
+----+---------+------------+---------+-----------+
| 17 | alias_2 | Product 2  | USA     | retail    |
+----+---------+------------+---------+-----------+
| 22 | alias_2 | Product 2  | BEL     | corporate |
+----+---------+------------+---------+-----------+
| 25 | alias_2 | Product 2  | BEL     | retail    |
+----+---------+------------+---------+-----------+
| 22 | alias_3 | Product 3  | BEL     | corporate |
+----+---------+------------+---------+-----------+
| 25 | alias_3 | Product 3  | BEL     | retail    |
+----+---------+------------+---------+-----------+

我想要的输出是:

+----------+---------------+------------+-----------+----------+---------------+------------+-----------+
| t1_alias | t1_short_name | t1_country | t1_role   | t2_alias | t2_short_name | t2_country | t2_role   |
+----------+---------------+------------+-----------+----------+---------------+------------+-----------+
| alias_1  | Product 1     | USA        | retail    | alias_1  | Product 1     | USA        | retail    |
+----------+---------------+------------+-----------+----------+---------------+------------+-----------+
| alias_1  | Product 1     | USA        | corporate | alias_1  | Product 1     | USA        | corporate |
+----------+---------------+------------+-----------+----------+---------------+------------+-----------+
| alias_1  | Product 1     | POL        | retail    | <NULL>   | <NULL>        | <NULL>     |  <NULL>   |
+----------+---------------+------------+-----------+----------+---------------+------------+-----------+
| alias_1  | Product 1     | BEL        | corporate | <NULL>   | <NULL>        | <NULL>     |  <NULL>   |
+----------+---------------+------------+-----------+----------+---------------+------------+-----------+
| alias_2  | Product 2     | USA        | retail    | alias_2  | Product 2     | USA        | retail    |
+----------+---------------+------------+-----------+----------+---------------+------------+-----------+
| alias_2  | Product 2     | BEL        | corporate | alias_2  | Product 2     | BEL        | corporate |
+----------+---------------+------------+-----------+----------+---------------+------------+-----------+
| alias_2  | Product 2     | BEL        | retail    | alias_2  | Product 2     | BEL        | retail    |
+----------+---------------+------------+-----------+----------+---------------+------------+-----------+
| <NULL>   | <NULL>        | <NULL>     |  <NULL>   | alias_1  | Product 1     | POL        | corporate |
+----------+---------------+------------+-----------+----------+---------------+------------+-----------+
| <NULL>   | <NULL>        | <NULL>     |  <NULL>   | alias_1  | Product 1     | BEL        | retail    |
+----------+---------------+------------+-----------+----------+---------------+------------+-----------+
| <NULL>   | <NULL>        | <NULL>     |  <NULL>   | alias_3  | Product 3     | BEL        | corporate |
+----------+---------------+------------+-----------+----------+---------------+------------+-----------+
| <NULL>   | <NULL>        | <NULL>     |  <NULL>   | alias_3  | Product 3     | BEL        | retail    |
+----------+---------------+------------+-----------+----------+---------------+------------+-----------+

这可能吗?我尝试了很多尝试,我最近的一次是在这里。 https://www.db-fiddle.com/f/6oSg88qu9N38BWpNnWTtfL/2

谢谢

您想要的结果是模拟 FULL OUTER 连接。
实现解决方案的方法是通过UNION模拟FULL OUTER连接并在RIGHT连接的WHERE子句中应用条件的常见技巧:

SELECT 
  table_1.alias t1_alias, table_1.short_name t1_short_name, 
  table_1.country t1_country, table_1.role t1_role,
  table_2.alias t2_alias, table_2.short_name t2_short_name, 
  table_2.country t2_country, table_2.role t2_role
FROM table_1
LEFT JOIN table_2 
ON table_1.alias = table_2.alias AND table_1.short_name = table_2.short_name 
AND table_1.country = table_2.country
AND table_1.role = table_2.role
UNION ALL
SELECT 
  table_1.alias t1_alias, table_1.short_name t1_short_name, 
  table_1.country t1_country, table_1.role t1_role,
  table_2.alias t2_alias, table_2.short_name t2_short_name, 
  table_2.country t2_country, table_2.role t2_role
FROM table_1
RIGHT JOIN table_2 
ON table_1.alias = table_2.alias AND table_1.short_name = table_2.short_name 
AND table_1.country = table_2.country
AND table_1.role = table_2.role
WHERE table_1.alias IS NULL
ORDER BY t1_alias IS NULL, t1_alias

参见demo
结果:

| t1_alias | t1_short_name | t1_country | t1_role   | t2_alias | t2_short_name | t2_country | t2_role   |
| -------- | ------------- | ---------- | --------- | -------- | ------------- | ---------- | --------- |
| alias_1  | Product 1     | USA        | retail    | alias_1  | Product 1     | USA        | retail    |
| alias_1  | Product 1     | USA        | corporate | alias_1  | Product 1     | USA        | corporate |
| alias_1  | Product 1     | POL        | retail    |          |               |            |           |
| alias_1  | Product 1     | BEL        | corporate |          |               |            |           |
| alias_2  | Product 2     | USA        | retail    | alias_2  | Product 2     | USA        | retail    |
| alias_2  | Product 2     | BEL        | corporate | alias_2  | Product 2     | BEL        | corporate |
| alias_2  | Product 2     | BEL        | retail    | alias_2  | Product 2     | BEL        | retail    |
|          |               |            |           | alias_1  | Product 1     | POL        | corporate |
|          |               |            |           | alias_1  | Product 1     | BEL        | retail    |
|          |               |            |           | alias_3  | Product 3     | BEL        | corporate |
|          |               |            |           | alias_3  | Product 3     | BEL        | retail    |