问题描述
select user_id as "user",(case when userBad then CodeRed
else CodeBlue
end)
From colours
我想为CodeRed列分配别名Red,为CodeBlue列分配别名Blue。我知道我不能在case语句中使用别名。那么分配条件别名的正确语法是什么?我以为也许我声明了一个字符串变量来保存别名的值,然后将该变量附加到case语句中:
declare alias varchar(4);
if userBad then set alias = "Red"
else set alias = "Blue";
select user_id as "user",(case when userBad then CodeRed
else CodeBlue
end) as alias
From colours;
但是,正如您可能期望的那样,我最后得到一列称为别名!那么有没有一种方法可以根据案例选择来分配条件别名?谢谢
更新:Slava通过使用准备好的语句来别名化变量提供了一个很好的解决方案。我的完整代码:我现在收到错误1054:“字段列表”中的未知列userBad,但我相信Slava已将我带入正确的轨道。
PROCEDURE `Test`(userBad bool)
BEGIN
declare alias varchar(4);
drop temporary table if exists colours;
create temporary table colours (user_id int,codeRed int,codeBlue int);
if userBad then set alias = "Red";
else set alias = "Blue";
end if;
SET @sql = CONCAT('select user_id as "user",(case when userBad = true then codeRed
else codeBlue
end) as ',alias,' from colours');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
最终更新:我已经解决了“ 1054:“字段列表”中的未知列userBad”错误。我在下面发布了完整的工作解决方案。感谢Slava,让我正确地使用了准备好的语句。
解决方法
在存储过程中,您可以执行以下操作:
declare alias varchar(4);
if userBad then alias = "Red"
else alias = "Blue";
SET @sql = CONCAT('select user_id as ',alias,' from colours');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
上面的代码仅说明了动态查询的思想。您所查询的情况可能有所不同。
在完整的存储过程代码下面。
PROCEDURE `Test`(userBad bool)
BEGIN
declare alias varchar(4);
drop temporary table if exists colours;
create temporary table colours (user_id int,codeRed int,codeBlue int);
if userBad then
set alias = "Red";
else
set alias = "Blue";
end if;
SET @sql = CONCAT(
'select user_id as "user",code',' as ',' from colours'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
另一个代码:
PROCEDURE `Test`(userBad bool)
BEGIN
drop temporary table if exists colours;
create temporary table colours (user_id int,codeBlue int);
if userBad then
SET @sql = 'select user_id as "user",codeRed as Red from colours';
else
SET @sql = 'select user_id as "user",codeBlue as Blue from colours';
end if;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
,
我要感谢Slava使用准备好的语句使我走上正轨。这是一个封闭的解决方案,效果不佳,其他解决方案也不是必需的结果。
解决方案是准备好的语句,但是存在一个问题,即变量 userBad 被拒绝。我意识到的是,在准备好的语句中不能有变量,但是可以有一个占位符值,用?表示,然后使用 userBad 执行该语句。但是,这仍然会产生错误,因为执行准备好的语句的USING子句需要用户/会话变量,而不是局部变量。因此,需要将本地变量 userBad 分配给会话变量@uB。完整的工作解决方案如下:
PROCEDURE `Test`(userBad int)
BEGIN
declare alias varchar(4);
drop temporary table if exists colours;
create temporary table colours (user_id int,codeBlue int);
if userBad then set alias = "Red";
else set alias = "Blue";
end if;
set @uB = userBad;
SET @sql = CONCAT('select user_id as "user",(case when ? then codeRed
else codeBlue
end) as ',' from colours');
PREPARE stmt FROM @sql;
EXECUTE stmt using @uB;
DEALLOCATE PREPARE stmt
END
对于需要这种解决方案的那些人,要添加的另一件事是,如果您有多个会话变量,则需要按语句中使用的顺序列出这些变量。