【问题标题】:can MySQL temporary variables be used in WHERE clause?可以在 WHERE 子句中使用 MySQL 临时变量吗?
【发布时间】:2014-08-28 06:38:45
【问题描述】:

在MySQL中,可以在WHERE子句中使用临时变量吗?

例如,在以下查询中:

SELECT `id`, @var := `id` * 2 FROM `user`

@var 成功设置为 `id` 值的两倍

但是,如果我尝试过滤结果集以仅包含 @var 小于 10 的结果:

SELECT `id`, @var := `id` * 2 FROM `user` WHERE @var < 10

然后我没有得到任何结果。

如何根据@var 的值过滤结果?

【问题讨论】:

  • SELECT id, @var := id * 2 FROM user WHERE id &lt; 5 ? (抱歉,忍不住……)
  • SELECT 子句中声明的任何内容都只能在HAVING 中引用。 WHERE 只能访问表数据。
  • @Pixelchemist 哈哈,谢谢。但是,我正在寻找一种过滤临时变量而不是表列的方法。在我们的实际查询中,@var 的取值是基于更复杂的逻辑,在SELECTWHERE 子句中重复逻辑是多余的。
  • @Barmar 以下查询也不起作用:SELECT `id`, @var := `id` * 2 FROM `user` HAVING @var &lt; 10

标签: mysql variables where where-clause temporary


【解决方案1】:

您需要分配一个别名,并在HAVING 子句中对其进行测试:

SELECT id, @var := id * 2 AS id_times_2
FROM user
HAVING id_times_2 < 10

请注意,如果您只是使用公式进行过滤,而不是将内部结果从一行传递到下一行,则根本不需要该变量。你可以写:

SELECT id, id * 2 AS id_times_2
FROM user
HAVING id_times_2 < 10

【讨论】:

  • 严格来说,HAVING子句中的谓词是not “基于@var的值”。请注意,可以从语句中删除对用户定义变量 @var := 的赋值,并且返回的结果将完全相同。 (不同之处在于为用户定义的变量分配了一个值,这将根据处理的最后一行来确定。)
  • 好点,我添加了一个不使用变量的查询。用户变量一般只需要在行之间传递值,例如运行总计、行计数器等。
【解决方案2】:

问:MySQL 临时变量可以用在 WHERE 子句中吗?

是的。 MySQL 用户定义的变量(例如@var)可以在 WHERE 子句中引用。

用户定义的变量是对当前分配给它的任何值的引用在计算表达式时

在您的查询中,WHERE 子句中的谓词在 SELECT 列表中的表达式之前进行评估。

也就是说,@var &lt; 10 在访问行时被评估为布尔表达式;对于每个候选行,计算表达式,并且仅当结果为 TRUE 时才返回该行。

如果您要为该变量提供一个数值大于或等于 10 的值,则在执行语句之前,将返回所有行。

问:如何根据@var 的值过滤结果?

你真的不能。 (实际上,这就是您的原始查询所做的。)

您可以在表达式 other 上包含谓词而不是@var;并且这些表达式可以从分配给@var的值派生出来。

作为一种选择,您可以在 SELECT 列表中返回一个表达式,然后使用 HAVING 子句过滤返回的行。 (注意:HAVING 子句在结果集准备好之后进行评估;与WHERE 子句不同,它在访问行时进行评估。)

另一种选择是使用内联视图来准备结果集,然后外部查询可以在返回的表达式上使用 WHERE 子句。

但严格来说,这些方法都在表达式 other 上应用谓词而不是@var;他们实际上并没有对@var 中的值进行测试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 2018-04-12
    • 2017-07-18
    • 2017-05-07
    相关资源
    最近更新 更多