我有一个数据库(MySQL 5.1),它使用交叉引用表(下例中的 local_ref)来获取值的数字 ID。我引入了另一个交叉引用表(foreign_ref,如下),以将这些数字 ID 引用到另一个数据库中的索引。通常这不是一个复杂的连接,但是,我有多个列使用交叉引用表(下面的 val1 和 val2)中的键。
例如:
mysql> select * from foo;
+-----+------+------+
| id | val1 | val2 |
+-----+------+------+
| 100 | A | B |
| 200 | A | D |
| 300 | B | C |
+-----+------+------+
mysql> select * from local_ref;
+----+-------+
| id | value |
+----+-------+
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
| 5 | E |
+----+-------+
mysql> select * from foreign_ref;
+----------+------------+
| local_id | foreign_id |
+----------+------------+
| 1 | 10 |
| 2 | 20 |
| 3 | 30 |
| 4 | 40 |
+----------+------------+
我需要的是以下内容:
+-----+---------+---------+
| id | val1_id | val2_id |
+-----+---------+---------+
| 100 | 10 | 20 |
| 200 | 10 | 40 |
| 300 | 20 | 30 |
+-----+---------+---------+
知道原始表未按应有的规范化,我通过以下两种方式获得了结果:
对两个交叉引用表进行两次别名:
SELECT
FOO.id, F_R1.foreign_id, F_R2.foreign_id
FROM FOO
JOIN
Local_Ref as L_R1 ON (FOO.val1 = L_R1.value)
JOIN
Local_Ref as L_R2 ON (FOO.val2 = L_R2.value)
JOIN
Foreign_Ref as F_R1 ON (L_R1.id = F_R1.local_id)
JOIN
Foreign_Ref as F_R2 ON (L_R2.id = F_R2.local_id)
将交叉引用表连接两次并为每个连接设置别名。
SELECT
FOO.id, joint1.foreign_id, joint2.foreign_id
FROM
FOO
JOIN
(
SELECT * FROM Local_Ref JOIN Foreign_Ref ON Local_Ref.id = Foreign_Ref.local_id
) as joint1
ON FOO.val1 = joint1.value
JOIN
(
SELECT * FROM Local_Ref JOIN Foreign_Ref ON Local_Ref.id = Foreign_Ref.local_id
) as joint2
ON FOO.val2 = joint2.value
我觉得这两种方法都非常低效,可以改进。除了重建数据库,还有没有更高效的解决方案?