【问题标题】:Query dynamic mysql column查询动态mysql列
【发布时间】:2019-01-23 14:22:11
【问题描述】:

以下可能吗?

SELECT f.*, (SELECT QUERY WHICH PULLS OUT A STRING VALUE) AS record_type
FROM foo f
AND f.record_type > 0

基本上我想查询一个动态列。我还尝试了以下我没有任何运气的方法:

SELECT f.*
FROM foo f
AND f.(SELECT QUERY WHICH PULLS OUT A STRING VALUE) > 0

这在 mysql 中甚至可能吗?

【问题讨论】:

标签: mysql sql dynamic


【解决方案1】:

我们要做什么并不完全清楚。

是的,我们可以在 SELECT 列表中包含一个子查询。 (限制是子查询必须返回一个列,并且返回不超过一行)。这将是一个返回的

返回的值将被解释为对外部查询中列的引用。

我们可以在HAVING子句中引用子查询返回的值,例如

 SELECT f.id 
      , ( SELECT t.fee FROM t WHERE t.fi = 'fo' LIMIT 1 ) AS fum
   FROM f
 HAVING fum > 0

请注意,我们不能在查询的 WHERE 子句中引用 fum

另请注意,我们没有将 fum 限定为 f.,因为 fum 不是 f 中的列。

我们可以使查询成为内联视图,然后外部查询可以在WHERE 子句中引用fum

但就效率而言,所有这些都不太理想。该查询将从f 访问每一 行,并在访问所有行之后应用HAVING 子句中的条件。

再次...子查询返回的值是一个在结果集中返回的;这不会被解释为对 f 中列的引用。

除非这是一个相关子查询,否则子查询将为f 中的每一行返回相同的值,因此它本质上是一个文字值。

如果这是一个相关子查询(在外部查询中包括对来自f 的列的引用),那么JOIN 操作可能会更好地满足规范。

同样,我们要达到的目标并不完全清楚。


如果目标是对列的动态 引用,那么不,这不能在单个 SQL 语句中实现。

要使用 SQL 动态生成列引用,这需要 单独的 SQL 语句,然后可以使用该结果生成我们要运行的 SQL 语句。

另一种方法是制作一个包含对多个列的静态引用的表达式,包括表达式中确定应从哪些静态列引用中返回值的逻辑。

【讨论】:

  • 非常感谢您的全面回复,我追求的是后者(动态参考)。这似乎并不那么简单,因为这是该站点中使用频率很高的部分。我认为最明智的做法是在 PHP 中编写一个过滤器函数,因为 SQL 看起来太乱了,我不喜欢。非常感谢您的帮助。
【解决方案2】:

您可以动态构建查询:

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;

Rextester Demo

【讨论】:

    【解决方案3】:

    通过一些疯狂的混合程序,这可能是可能的,但并不常见,我建议你不要这样做,因为它会导致严重的安全漏洞。

    对于简单的查询或带有绑定的预处理语句,这绝对是不可能的。 您可以在您的 select 命令中创建一个 case-block 来确定要使用的列,但仅此而已。

    【讨论】:

      猜你喜欢
      • 2015-10-01
      • 2013-01-27
      • 1970-01-01
      • 2013-03-26
      • 2013-05-08
      • 2021-08-05
      • 2016-08-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多