人々は、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:EXPLAIN
次のように評価される条件を持つクエリの部分のMySQLは次のようになりますFALSE
。
部分に注意してくださいImpossible WHERE
。MySQLは、の式WHERE
が常にに評価されていることを認識しているFALSE
ため、クエリを実行しようとさえしません。したがって、このアプローチを使用する場合、パフォーマンスのオーバーヘッドはありません。
(回答へのアップグレード)
どこvar
から来たの?
それが別の言語の変数である場合は、その別の言語でテストしてから、必要に応じて別のSQLを作成できます。
$sql = "SELECT amount FROM " . ($var = 1 ? "mytable1" : "mytable2");
SQLのユーザー変数の場合は、2つの代替ステートメントの前後に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;