使用特定列根据另一列

时间:2018-03-02 01:15:12

标签: mysql sql database-design sql-update

我在设计的数据库中遇到以下情况......

**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]值多少,它都需要工作。

3 个答案:

答案 0 :(得分:1)

您可以使用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 );

答案 1 :(得分:1)

您可以尝试使用更新加入:

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,因此订单在那里无关紧要。

我们可以尝试使用单个连接执行此操作,但是具有非常复杂逻辑的连接条件可能是真正的性能杀手。

答案 2 :(得分:0)

这是一个将产生您搜索结果的选择。

case Foo(a) && Bar(b) && Baz(c) => ...

您可以在视图中使用它,或者使用以下命令将其插入到新表中

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
...