我在设计的数据库中有以下情况......
**Value Table**
+-------+------------+-----------+------------+---------+-------+--------+
| id | use_col | col_1 | col_2 | col_3 | … etc | Lookup |
+-------+------------+-----------+------------+---------+-------+--------+
| 1 | col_1 | 0.5 | no | low | … | ? |
| 2 | col_2 | 0.1 | yes | low | … | ? |
| 3 | col_3 | 0.2 | no | high | … | ? |
| … etc | … | … | … | … | … | … |
+-------+------------+-----------+------------+---------+-------+--------+
**Lookup Table**
+------------+-------------+--------+
| use_col | Value Range | Lookup |
+------------+-------------+--------+
| col_1 | 0.1 | 5 |
| col_1 | 0.2 | 4 |
| col_1 | 0.3 | 3 |
| col_1 | 0.4 | 2 |
| col_1 | 0.5 | 1 |
| col_2 | no | 5 |
| col_2 | yes | 1 |
| col_3 | low | 4 |
| col_3 | medium | 3 |
| col_3 | high | 2 |
| col_3 | very high | 1 |
| … etc | … | … |
+------------+-------------+--------+
我需要使用与[use_col]字段关联的字段中的值来返回[查找表]中的匹配[查找]并将该值写入[值表]。即我的决赛桌需要包含以下信息。
+-------+------------+-----------+------------+---------+-------+--------+
| id | use_col | col_1 | col_2 | col_3 | … etc | Lookup |
+-------+------------+-----------+------------+---------+-------+--------+
| 1 | col_1 | 0.5 | no | low | … | 1 |
| 2 | col_2 | 0.1 | yes | low | … | 1 |
| 3 | col_3 | 0.2 | no | high | … | 2 |
| … etc | … | … | … | … | … | … |
+-------+------------+-----------+------------+---------+-------+--------+
如何编写SQL UPDATE查询来执行此操作?请记住,无论数据结构中的[use_col]值多少,它都需要工作。
您可以使用join
构建表:
select vt.*, l.lookup
from valuetable vt left join
lookup l
on vt.use_col = l.use_col and
( (vt.user_col = 'col1' and vt.col1 = l.value) or
(vt.user_col = 'col2' and vt.col2 = l.value) or
(vt.user_col = 'col3' and vt.col3 = l.value)
)
在您的示例中,所有查找值都不同,因此您可以将其简化为:
select vt.*, l.lookup
from valuetable vt left join
lookup l
on vt.use_col = l.use_col and
l.value in ( vt.col1, vt.col2, vt.col3 );
您可以尝试使用更新联接:
UPDATE Value v
INNER JOIN Lookup l1
ON v.col_1 = l1.value_range AND l1.use_col = 'col_1'
INNER JOIN Lookup l2
ON v.col_2 = l2.value_range AND l2.use_col = 'col_2'
INNER JOIN Lookup l3
ON v.col_3 = l3.value_range AND l3.use_col = 'col_3'
SET v.Lookup = COALESCE(l1.Lookup, l2.Lookup, l3.Lookup);
上面的COALESCE
表达式将采用它遇到的第一个非NULL
查找值。您的示例数据意味着只有一个查找值不是非NULL
,因此顺序在那里无关紧要。
我们可以尝试使用单个连接执行此操作,但具有非常复杂逻辑的连接条件可能是真正的性能杀手。
这是一个将产生您搜索结果的选择。
select a.use_col, a.col_1, a.col_2, a.col_3, b.look_up
from value_table a, look_up_table b
where a.use_col = b.use_col
and a.use_col = 'col_1'
and a.col_1 = b.value_range
union
select a.use_col, a.col_1, a.col_2, a.col_3, b.look_up
from value_table a, look_up_table b
where a.use_col = b.use_col
and a.use_col = 'col_2'
and a.col_2 = b.value_range
union
select a.use_col, a.col_1, a.col_2, a.col_3, b.look_up
from value_table a, look_up_table b
where a.use_col = b.use_col
and a.use_col = 'col_3'
and a.col_3 = b.value_range
union
...
您可以在视图中使用它,或者将其插入到新表中,其中包含:
inset into result_table select (put here the query)