Mysql 具有动态列名的SQL SELECT语句
我尝试选择那些名称是其他列内容的列。我正在使用MySQL 5.6 假设我有“表1”: 及“表二”: 我要做的是:连接table1和table2,table2.type字段包含我要从table1中选择的列的名称。还有一个问题是,type字段只包含我必须扩展的缩写。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, '
这将在以下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