【问题标题】:Returning a value even if no result即使没有结果也返回一个值
【发布时间】:2012-09-09 02:48:13
【问题描述】:

我有这种简单的查询,它为给定的 id 返回一个非空整数字段:

SELECT field1 FROM table WHERE id = 123 LIMIT 1;

问题是如果没有找到 id,结果集是空的。我需要查询始终返回一个值,即使没有结果。

我有这个东西工作,但我不喜欢它,因为它运行相同的子查询 2 次:

SELECT IF(EXISTS(SELECT 1 FROM table WHERE id = 123) = 1, (SELECT field1 FROM table WHERE id = 123 LIMIT 1), 0);

如果该行存在则返回field1,否则返回0。有什么方法可以改进吗?

谢谢!

编辑以下一些 cmets 和答案:是的,它必须在 单个查询语句中,我不能使用计数技巧,因为 我需要返回只有 1 个值(仅供参考,我使用 Java/Spring 方法 SimpleJdbcTemplate.queryForLong() 运行查询)。

【问题讨论】:

  • 这需要在单个查询语句中完成吗?否则,您可以使用默认值声明一个变量,选择其中,然后选择该变量。

标签: mysql


【解决方案1】:

如果结果为空,MySQL 有一个返回值的函数。您可以在整个查询中使用它:

SELECT IFNULL( (SELECT field1 FROM table WHERE id = 123 LIMIT 1) ,'not found');

【讨论】:

  • 很好地将整个查询放在 IFNULL 中!实际上我尝试了类似的方法: SELECT IFNULL(field1, 0) FROM table WHERE id = 123 LIMIT 1;但它不起作用(没有结果),我没有想到将整个查询放在 IFNULL ...
  • 这是对这个常见问题的最佳答案。旁注,COALESCE() 也可以代替IFNULL()。不确定是否存在性能差异,但我习惯了COALESCE(),所以更容易记住。
  • COALESCE() 将继续找不到空值。然后有多个参数。 techonthenet.com/mysql/functions/coalesce.php
  • 这需要运行 SELECT 语句两次。一次是检查是否可以找到,另一次是实际找到它。对于完全相同的结果,这是 MySQL 服务器上的负载的两倍。请参阅以下 MarkNHopGood 的解决方案。
  • 点赞!从来没有想过在整个查询中使用IFNULL
【解决方案2】:

当您正在寻找 1 条记录时,(LIMIT 1) 那么这将起作用。

(SELECT field1 FROM table WHERE id = 123) 
UNION 
(SELECT 'default_value_if_no_record')
LIMIT 1;

可以方便地显示默认值或指示未找到结果。我用它来做报告。

另请参阅http://blogs.uoregon.edu/developments/2011/03/31/add-a-header-row-to-mysql-query-results/,了解使用它在报告中创建标题的方法。

【讨论】:

  • 非常有用!!我用“null”(无引号)交换了“default_value_if_no_record”,它产生了所需的输出。完美,谢谢!
  • 聪明的朋友!
  • 是的,这是一篇相当老的帖子,但想提一下 union 不保证任何顺序,因此返回的 1 条目完全有可能是默认行而不是结果。我不知道有任何实现会真正打乱这个简单的结果集,但依赖这种行为真的不安全。 doc page 提到了这一点,并提供了一个涉及虚拟排序列的解决方案,如果你真的想使用这种方法,但它开始变得有点混乱。
  • 有时mysql会返回空字符串,UNION不会捕获。解决方案:(SELECT field1 FROM table WHERE id = 123 AND field1 <> '') UNION (SELECT 'default_value_if_no_record') LIMIT 1;
  • 正如@AC 提到的,UNION 不保证顺序,但是如果您尝试返回简单的 Y 或 N 标志,您可以为该字段设置别名并使用 ORDER BY 来确保您获得正确的顺序: (SELECT IF(field IS NULL, 'N', 'Y') AS flag FROM table WHERE id = 123) UNION (SELECT 'N' AS flag) ORDER BY flag DESC LIMIT 1;
【解决方案3】:

您可以包含 count(id)。那总会回来的。

select count(field1), field1 from table where id = 123 limit 1;

http://sqlfiddle.com/#!2/64c76/4

【讨论】:

  • 甚至:SELECT 1, field FROM table WHERE ...
  • 没有。那是行不通的。 min、max、sum 或大多数其他函数也不会。基本上我总是坚持数数,因为我知道这是有效的。
  • 哦,你说得对,我的印象是它有效,但实际上我只是尝试过,它没有
  • 这个不能用 GROUP by。
  • @Andreas Wederbrand 实际上 sum() 在正确使用时可以工作...例如 select ifnull(sum(record_number), 13) from bch_trans_file where 7=9;
【解决方案4】:

你可以使用COALESCE

SELECT COALESCE(SUM(column),0)
FROM   table

【讨论】:

    【解决方案5】:

    如果有人希望使用它来将结果插入到变量中,然后在存储过程中使用它;你可以这样做:

    DECLARE date_created INT DEFAULT 1;
    SELECT IFNULL((SELECT date FROM monthly_comission WHERE date = date_new_month LIMIT 1), 0) 
    INTO date_created 
    WHERE IFNULL((SELECT date FROM monthly_comission WHERE date = date_new_month LIMIT 1), 0) = 0;
    

    有了这个,你在变量 'date_created' 中存储 1 或 0(如果没有返回)。

    【讨论】:

      【解决方案6】:

      使用LEFT OUTER JOIN 进行搜索。我不知道 MySQL 是否允许在连接子句中内联 VALUES,但您可以为此目的使用预定义的表。

      【讨论】:

        【解决方案7】:

        k-a-f's answer适用于选择一列,如果选择多列,我们可以。

        DECLARE a BIGINT DEFAULT 1;
        DECLARE b BIGINT DEFAULT "name";
        
        SELECT id, name from table into a,b;
        

        然后我们只需要检查 a,b 的值。

        【讨论】:

          【解决方案8】:

          如果您希望两者都始终是返回值但绝不是空值,您可以将 count 与 coalesce 结合使用:

          select count(field1), coalesce(field1,'any_other_default_value') from table;
          

          因为 count, 将强制 mysql 总是返回一个值(如果没有要计算的值,则为 0),并且 coalesce 将强制 mysql 总是输入一个不为空的值

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-11-12
            • 2019-08-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-04-05
            • 1970-01-01
            相关资源
            最近更新 更多