Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 具有动态列名的SQL SELECT语句_Mysql_Sql_Select - Fatal编程技术网

Mysql 具有动态列名的SQL SELECT语句

Mysql 具有动态列名的SQL SELECT语句,mysql,sql,select,Mysql,Sql,Select,我尝试选择那些名称是其他列内容的列。我正在使用MySQL 5.6 假设我有“表1”: 及“表二”: 我要做的是:连接table1和table2,table2.type字段包含我要从table1中选择的列的名称。还有一个问题是,type字段只包含我必须扩展的缩写。 这将在以下SQL语句中结束: SELECT t1.id, IF(t2.type REGEXP 'i[0-9]+', REPLACE(t2.type, 'i', 'val_int'), REPLACE(t2.type, '

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

假设我有“表1”:

及“表二”:

我要做的是:连接table1和table2,table2.type字段包含我要从table1中选择的列的名称。还有一个问题是,type字段只包含我必须扩展的缩写。
这将在以下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
结果是REPLACE函数将val_int1和val_string2作为固定字符串返回,而不是作为列名处理

我真正期望的是:

+-----+-------+
|  1  |  70   |
|  1  |  yyy  |
+-----+-------+

您需要某种类型的
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;

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

使用case表达式,我将这样解决:

DECLARE @table1 TABLE
(
    id INT,
    val_int1 INT,
    val_int2 INT,
    val_string1 NVARCHAR(100),
    val_string2 NVARCHAR(100)
)

INSERT INTO @table1 VALUES
(1,70,88,'xxx','yyy')

DECLARE @table2 TABLE
(
    id INT,
    type NVARCHAR(MAX),
    ref_id INT
)

INSERT INTO @table2 VALUES
(10,'i1',1),
(20,'s2',1)

SELECT 
    id,
    CASE WHEN type = 'i1' THEN CAST((SELECT TOP 1 val_int1 FROM @table1) AS NVARCHAR(100)) ELSE 
        CASE WHEN type = 'i2' THEN CAST((SELECT TOP 1 val_int2 FROM @table1) AS NVARCHAR(100)) ELSE 
        CASE WHEN type = 's1' THEN (SELECT TOP 1 val_string1 FROM @table1) ELSE 
            (SELECT TOP 1 val_string2 FROM @table1) END END END
FROM @table2 t2
输出:

10  70
20  yyy

我选择了第二种解决方案,因为您可以在这里不使用子查询。注意:在MySQL 5.6下,无法强制转换为VARCHAR。@altralaser。这个问题没有为MySQL添加标签。它没有显式地添加标签,但我肯定是在我的问题中写的。
DECLARE @table1 TABLE
(
    id INT,
    val_int1 INT,
    val_int2 INT,
    val_string1 NVARCHAR(100),
    val_string2 NVARCHAR(100)
)

INSERT INTO @table1 VALUES
(1,70,88,'xxx','yyy')

DECLARE @table2 TABLE
(
    id INT,
    type NVARCHAR(MAX),
    ref_id INT
)

INSERT INTO @table2 VALUES
(10,'i1',1),
(20,'s2',1)

SELECT 
    id,
    CASE WHEN type = 'i1' THEN CAST((SELECT TOP 1 val_int1 FROM @table1) AS NVARCHAR(100)) ELSE 
        CASE WHEN type = 'i2' THEN CAST((SELECT TOP 1 val_int2 FROM @table1) AS NVARCHAR(100)) ELSE 
        CASE WHEN type = 's1' THEN (SELECT TOP 1 val_string1 FROM @table1) ELSE 
            (SELECT TOP 1 val_string2 FROM @table1) END END END
FROM @table2 t2
10  70
20  yyy