具有动态列名的SQL SELECT语句

alt*_*ser 2 mysql sql select

我尝试选择名称为其他列内容的列。我正在使用MySQL 5.6。

假设我有“ table1”:

+------+------------+------------+---------------+---------------+
|  id  |  val_int1  |  val_int2  |  val_string1  |  val_string2  |
+------+------------+------------+---------------+---------------+
|  1   |  70        |  88        |  xxx          |  yyy          |
+------+------------+------------+---------------+---------------+
Run Code Online (Sandbox Code Playgroud)

和“ table2”:

+------+--------+----------+
|  id  |  type  |  ref_id  |
+------+--------+----------+
|  10  |  i1    |  1       |
|  20  |  s2    |  1       |
+------+--------+----------+
Run Code Online (Sandbox Code Playgroud)

我想要做的是:将table1和table2连接起来,table2.type字段包含要选择的table1中的列的名称。还有一个问题,类型字段仅包含我必须扩展的缩写。
这以以下SQL语句结束:

SELECT
    t1.id,
    IF(t2.type REGEXP 'i[0-9]+', REPLACE(t2.type, 'i', 'val_int'), REPLACE(t2.type, 's', 'val_string'))
FROM
    table1 t1, table2 t2
WHERE
    t1.id = t2.ref_id AND t1.id = 1
Run Code Online (Sandbox Code Playgroud)

结果是REPLACE函数将val_int1和val_string2作为固定字符串返回,而不将其作为列名称进行处理。

我真正期望的是:

+-----+-------+
|  1  |  70   |
|  1  |  yyy  |
+-----+-------+
Run Code Online (Sandbox Code Playgroud)

Gor*_*off 5

您需要某种case表达方式:

select t1.id,
       (case when t2.type = 'i1' then cast(val_int_1 as varchar(255))
             when t2.type = 'i2' then cast(val_int_2 as varchar(255))
             when t2.type = 's1' then val_string_1
             when t2.type = 's2' then val_string_2
        end) as val
from table1 t1 cross join
     table2 t2;
Run Code Online (Sandbox Code Playgroud)

您可能会抱怨“哦,我有那么多专栏”。基本上太糟糕了。您的数据库设计不佳。您正在尝试对字符串和列名进行部分匹配。即使是动态SQL解决方案也不是很可行。