如何并排比较两个 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 |
我有两个 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 |