如果未找到行,则返回默认值。

11

我正在构建一个查询来从数据库中搜索多行,例如

SELECT 
  * 
FROM
  table1 
WHERE col1 = '012311' 
  OR col1 = '0123631' 
  OR col1 = '091233' 
  OR col1 = '092111' 

这里返回了前3个值,因为它们存在于表中,但对于最后一个值没有返回任何内容,因为它不在表格中。那么如果查询没有找到该值,我如何在查询中设置默认值?


1
听起来你需要使用MySQL的CASE语句:http://dev.mysql.com/doc/refman/5.0/en/case.html - Jongosi
默认值意味着显示示例输出。 - Sathish
默认意味着“未找到”,“记录不存在”等。 - Jadeja RJ
7个回答

12

有几种方法,这取决于数据集。以下是其中一种方法:

SELECT *, 
IFNULL(
    ( SELECT col1 FROM table1 
        WHERE col1 IN ('012311','0123631','091233','092111') 
    ),
    'some_value'
) AS my_col1
FROM table1;

并不是必须要复制粘贴,你需要根据你的具体情况进行调整。


不起作用……当没有找到值时,它没有返回任何内容。 - Jadeja RJ

11

在MySQL中,您可以使用IFNULL函数,在没有找到行(即返回NULL)时返回指定的值。例如:

SELECT IFNULL( (SELECT col1 FROM table1 WHERE col1 in (your_list)) ,'default_value_you_want_to_return');

你可以在IFNULL示例中看到示例。


它返回错误“操作数应包含1个列”。 - Jadeja RJ
1
在子查询中使用 SELECT * FROM 是错误的,无论如何都会减慢整个查询的速度。 - Jongosi
如果嵌套查询在同一张表上,您不能在INSERT SELECT中使用它。 - Pr Shadoko

3
我认为最好的方法是这样的:
SELECT COALESCE(col1, 'defaultValue') col1, COUNT(*) cRows 
FROM table1 
WHERE colx = 'filter';

这个查询返回了2列:

  • 第一列是搜索的列的值,如果行不存在,则使用默认值设置。
  • 第二列返回表中过滤器匹配的行数。

3

Use UNION

SELECT col_x FROM table_x
UNION
SELECT 'default_value';

'default_value'可以是任何数据类型。


这是可行的方法。如果没有返回初始行,合并方法将无法使用。 - Vitalis
这将在空数据库上显示两行,查询语句如下:SELECT MAX(TIMESTAMPDIFF(SECOND, created_at, updated_at)) as maxWait FROM my_table UNION select 0,其中一行为null,另一行为0 - undefined

2

我想对这个2.5年前的问题发表意见,并基于WHERE子句的假设,认为Jadeja RJ只想返回四行而不是整个表(也许表有10万行,使结果集非常臃肿)。

我不想在SELECT语句中使用贪婪的*,所以我将使用col1作为行标识符,col2作为其相关值。当然,可以根据需要指定更多列。 以下是一种硬编码所需行数并标记缺失行的方法:

SELECT hardrows.col1,IFNULL(table1.col2,'Not Found')
FROM 
(
    (SELECT '012311' AS `col1`) UNION 
    (SELECT '0123631') UNION 
    (SELECT '091233') UNION 
    (SELECT '092111')
) AS `hardrows`
LEFT JOIN `table1`
    ON hardrows.col1=table1.col1;

诚然,我这个建议是基于多种假设的。我不知道表中有多少行,需要声明多少硬编码行,也不知道实际查询是否有其他从句/表达式,可能导致其效率低下。优点仅在于控制返回的行数。

最后,如果标识符数组由另一个数据库表提供,则该表应替换hardrows


1
谢谢。它对我有用,除了我使用了UNION ALL而不是只使用UNION。其他答案都没有起作用。 - VHS

0

我写这篇文章是为了解决一个子场景的问题。我发布了一个适用于所有已分组查询的人的解决方案,以及像我一样想要在CASE 1中实现逻辑在带有WHERE子句的查询返回NO ROWS时具有默认值的行,以及在CASE 2中展示了一些过滤多个行的方法。

希望这能帮到你们。

CASE 1

一种方法是在默认值集合你想要过滤的行的集合之间使用UNION运算符。

你可以这样做:

  1. 使用您的默认值创建SELECT语句。
  2. 然后将第1个SELECT语句与所需的查询(添加一些WHERE子句、GROUP BY或其他任何内容)联接起来。为了演示目的,我们将查询id列。
  3. 添加列row_number,其中默认设置row_number = 0,查询设置row_number = 1
  4. row_number列以DESC顺序排序(为了始终将过滤行放在第一位)order by row_number desc
  5. 然后查询整个语句并通过LIMIT限制结果为1
    • 这将返回过滤行(如果有)默认行带有过滤行的结果
|  id  |   avg_column_val   |    row_number    |
------------------------------------------------
|  80  |          1         |        1         |
|   0  |          0         |        0         |

当你使用LIMIT 1时,你将获得筛选后的行

或者

默认行数的结果

|  id  |   avg_column_val   |   row_number   |
----------------------------------------------
|   0  |          0         |       0        |

当你使用LIMIT 1时,将会获取默认的行。


最终查询

select * from (
        select 0 as id, 0 as avg_column_val, 0 as row_number 
            union
        select t.id, avg(some_column) as avg_column_val, 1 as row_number
        from t_table as t 
        where t.id = @p_id
        group by t.id
        order by row_number desc
    ) as temp 
    limit 1;

CASE 2

当然,如果你想从WHERE CLAUSE返回更多行,可以执行查询并COUNT(*)结果以检查是否存在任何行

然后,您可以通过计数的行来限制它们并将其返回:(+1是在@p_counted_rows = 0且您想返回默认值的情况下)

请注意,您应该SQL_SELECT_LIMIT设置为计算查询(Set SQL_SELECT_LIMIT = @p_counted_rows + 1;) -> 这将限制确切数量的行,而无需编写LIMIT CLAUSE。 完成查询后,请将SET SQL_SELECT_LIMIT设置为DEFAULT (Set SQL_SELECT_LIMIT = Default;)

- This needs to be done because **LIMIT clause cannot use variable**.

最终查询

set @p_counted_rows = 0;

select @p_counted_rows = count(*)
from 
t_table as t
where t.id = @p_id;

Set SQL_SELECT_LIMIT = @p_counted_rows + 1;

select * from (
        select 0 as id, 0 as avg_column_val, 0 as row_number 
            union
        select t.id, avg(some_column) as avg_column_val, 1 as row_number
        from t_table as t 
        where t.id = @p_id
        order by row_number desc
    ) as temp;

Set SQL_SELECT_LIMIT = Default;

希望这对大家有所帮助。
祝大家编程愉快!

-1
SELECT
     CASE WHEN col1 = NULL THEN "NULL" ELSE col1 END AS 'col1'
FROM table1
WHERE
     col1 = '012311'
     OR col1 = '0123631'
     OR col1 = '091233'
     OR col1 = '092111'

这可能是您在格式方面寻找的内容。如果col1为NULL,则返回一个字符串“NULL”(可以替换)。如果col1不为NULL,则返回值结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接