人们知道我们可以像这样使用 if 语句在 select 语句中配置查询
select if(var=1,amount,amount/2) from mytable;
但是,如果我想实现这样的目标怎么办:
select amount from if(var=1,mytable1,mytable2);
有没有办法在运行时配置表?
SELECT amount FROM mytable1 WHERE @var = 1
UNION
SELECT amount FROM mytable2 WHERE @var = 0
UPD:下面是 MySQLEXPLAIN
的查询部分的样子,它的条件评估为FALSE
:
注意Impossible WHERE
部分。MySQL 认识到 in 中的表达式WHERE
不断评估为FALSE
,因此它甚至不会尝试执行查询。因此,使用这种方法时没有性能开销。
(升级到答案)
是从哪里来var
的?
如果它是另一种语言的变量,您可以用另一种语言对其进行测试,然后根据需要构造不同的 SQL:
$sql = "SELECT amount FROM " . ($var = 1 ? "mytable1" : "mytable2");
如果它是 SQL 中的用户变量,您可以类似地使用围绕两个替代IF
语句SELECT
的语句:
DELIMITER ;;
IF @var = 1 THEN
SELECT amount FROM mytable1;
ELSE
SELECT amount FROM mytable2;
END IF;;
DELIMITER ;
如果是其他任何内容(例如表中的字段),那么您的问题就没有多大意义。
根据 mysql 手册页,您似乎无法使用传统语法执行此操作。
“用户变量旨在提供数据值。它们不能直接在 SQL 语句中用作标识符或标识符的一部分,例如在需要表或数据库名称的上下文中,或作为保留字(如 SELECT) 。” - [http://dev.mysql.com/doc/refman/5.6/en/user-variables.html][1]
例外情况是您可以组装准备好的语句,但对于大多数编程任务可能不是更好的解决方案。最好将 sql 字符串的生成留给调用 mysql 的语言。
但是,如果您将此作为“仅限 sql”任务的一部分,例如导入,那么这似乎是您必须采用的方法。
SET @s = CONCAT("SELECT * FROM ", if(true, "table1", "table2"), " LIMIT 1");
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @s = CONCAT("SELECT * FROM ", if(false, "table1", "table2"), " LIMIT 1");
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;