【问题标题】:MySQL Return query result if condition is met, without repeating queryMySQL 满足条件返回查询结果,不重复查询
【发布时间】:2013-08-10 06:30:08
【问题描述】:

假设我有一些基本的东西

SELECT IF( (1 + 2) >=0, (1 + 2), 0)
FROM DUAL

显然会返回 3。

有没有办法不重复我想要返回的查询(这里是 1 + 2)?

作为上下文,我想返回当月剩余的任务数(至少必须完成 4 个),但如果已经完成了 4 个以上,则不需要再做更多所以我想要返回 0。

我所做的是

IF((4 - IFNULL((LONG QUERY RETURNING THE NUMBER OF TASKS DONE THIS MONTH FOR A PARTICULAR USER ),0)) >= 0,
(4 - IFNULL((LONG QUERY RETURNING THE NUMBER OF TASKS DONE THIS MONTH FOR A PARTICULAR USER ), 
0)

但是有没有办法不重复查询,因为它很长,我不希望服务器执行两次相同的查询?

【问题讨论】:

    标签: mysql if-statement


    【解决方案1】:

    一个语句解决方案

    在 MySQL 中解决此问题的一种方法是保存繁重查询的输出并多次重用。看这里:

    SELECT CASE 
      WHEN @Value - 4 > 0 
      THEN @Value ELSE 0 
      END
    FROM (SELECT @Value := (SELECT 1)) Query
    

    应将“SELECT 1”替换为您的查询。

    OT

    执行查询的另一种方式需要 CTE(通用表表达式)的支持。

    据我所知,MySQL 中缺少此功能 (How to transform a MSSQL CTE query to MySQL?)

    只是为了让您体验它在 MSSQL 中的表现力,在 CTE 可用的地方,您可以编写如下内容:

    with Query (value) 
    as
    (
        select 1
     )
    select 
      case
        when (select value from Query) - 4 > 0
          then (select value from Query)
        else
          0
      end
    

    CTE 确实更强大,尤其是在处理递归关系时。

    【讨论】:

      【解决方案2】:

      根据您的要求,您可能希望使用user-defined variables

      SELECT 1+2 INTO @tmp;
      SELECT IF( @tmp >=0, @tmp, 0)
      

      或者如果你喜欢一个衬里

      SELECT IF( (@tmp := (1+2)) >=0, @tmp, 0)
      --         ^             ^
      --        don't forget those parenthesis !
      

      编辑:这也适用于“表选择”语句:

      CREATE TABLE tbl AS SELECT 1 as a UNION SELECT 2;
      SELECT SUM(a) FROM tbl INTO @tmp;
      SELECT IF ( @tmp > 0, @tmp, 0);
      

      如果您查看上述查询的执行计划http://sqlfiddle.com/#!2/37c33/1,您将看到第二个SELECT don't use table。


      顺便说一句,请注意,在您的实际示例中,可以这样写:

      SELECT MAX( (1+2), 0 )
      --          ^^^^^ here your expression
      

      ...但我认为这不是您的真实查询的属性?

      【讨论】:

      • 问题是这是更大查询的一部分。它是 SELECT 语句的 select_expr 之一。我认为这不可能......
      • @JPP。您可能必须展示 actual 查询的示例。但据我所知,according to the doc, select_exprSELECT ... INTO 中是允许的
      • -从来没有第一条评论,在撰写本文时我没有看到您的编辑-我没想过要这样做MAX(),但既然您这么说了,它实际上会起作用。但我真正应该使用的方法是您提出的 one liner。我不知道我能做到这一点,谢谢!
      【解决方案3】:

      你可以这样做:

      SELECT IF( (@a:=(1 + 2)) >=0, @a, 0);
      

      【讨论】:

        猜你喜欢
        • 2021-10-27
        • 2018-10-14
        • 1970-01-01
        • 1970-01-01
        • 2020-03-25
        • 2016-07-12
        • 1970-01-01
        • 2023-02-09
        • 1970-01-01
        相关资源
        最近更新 更多