CREATE TABLE foo(id INT, record_type INT, a VARCHAR(2), b VARCHAR(2));
INSERT INTO foo(id, record_type, a, b)
VALUES (1,1,'a', 'a'), (2,0,'b', 'b'), (3,1, 'c', 'c');
SET @cols := (SELECT 'a'); -- or some select from metadata tables,
-- should be comma separated
SET @sql:= REPLACE('SELECT <cols> FROM foo f
WHERE f.record_type > 0', '<cols>', @cols);
PREPARE dynamic_statement FROM @sql;
EXECUTE dynamic_statement;
DEALLOCATE PREPARE dynamic_statement;
现在还不完全清楚我们要做什么。 是的,我们可以在选择列表中包含子查询(限制是子查询必须返回单个列,并且返回的行不能超过一行)。这将是一个返回的值。 返回的值不会被解释为对外部查询中列的引用。 我们可以在 HAVING 条款,例如。
SELECT f.id
, ( SELECT t.fee FROM t WHERE t.fi = 'fo' LIMIT 1 ) AS fum
FROM f
HAVING fum > 0
请注意,我们不能引用 fum 在查询的where子句中。 请注意,我们没有资格 fum 与 f. 因为 fum 不是中的列 f . 我们可以使查询成为内联视图,然后外部查询可以引用 fum 在一个 WHERE 条款。 但就效率而言,这一切都不太理想。查询将访问 f ,以及 HAVING 子句将在访问所有行之后应用。 再一次。。。子查询返回的值是在resultset中返回的值;这不会被解释为对f中某列的引用。 除非这是一个相关的子查询,否则子查询将为中的每一行返回相同的值 f ,所以它本质上是一个文本值。 如果这是一个相关子查询(其中包括对 f 在外部查询中),则可能是 JOIN 操作更符合规范。 再说一次,我们要达到的目标还不完全清楚。 如果目标是对列的动态引用,那么就不是了,这在单个sql语句中是无法实现的。 要使用sql动态生成列引用,需要一个单独的sql语句,然后可以使用该语句的结果生成要运行的sql语句。 另一种方法是创建一个表达式,其中包含对多个列的静态引用,包括表达式中的逻辑,用于确定应该从哪些静态列引用中返回值。
3条答案
按热度按时间6ss1mwsb1#
您可以动态生成查询:
rextester演示
bq9c1y662#
现在还不完全清楚我们要做什么。
是的,我们可以在选择列表中包含子查询(限制是子查询必须返回单个列,并且返回的行不能超过一行)。这将是一个返回的值。
返回的值不会被解释为对外部查询中列的引用。
我们可以在
HAVING
条款,例如。请注意,我们不能引用
fum
在查询的where子句中。请注意,我们没有资格
fum
与f.
因为fum
不是中的列f
.我们可以使查询成为内联视图,然后外部查询可以引用
fum
在一个WHERE
条款。但就效率而言,这一切都不太理想。查询将访问
f
,以及HAVING
子句将在访问所有行之后应用。再一次。。。子查询返回的值是在resultset中返回的值;这不会被解释为对f中某列的引用。
除非这是一个相关的子查询,否则子查询将为中的每一行返回相同的值
f
,所以它本质上是一个文本值。如果这是一个相关子查询(其中包括对
f
在外部查询中),则可能是JOIN
操作更符合规范。再说一次,我们要达到的目标还不完全清楚。
如果目标是对列的动态引用,那么就不是了,这在单个sql语句中是无法实现的。
要使用sql动态生成列引用,需要一个单独的sql语句,然后可以使用该语句的结果生成要运行的sql语句。
另一种方法是创建一个表达式,其中包含对多个列的静态引用,包括表达式中的逻辑,用于确定应该从哪些静态列引用中返回值。
ev7lccsx3#
有一些疯狂的混合程序,这可能是可能的,但并不常见,我建议你不要这样做,因为这将导致一个大的安全漏洞。
使用简单的查询或带有绑定的准备语句是绝对不可能的。您可以在select命令中创建一个case块来确定要使用哪一列,但基本上就是这样。