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

l3zydbqr  于 2023-02-03  发布在  Mysql
关注(0)|答案(7)|浏览(422)

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

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

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

sirbozc5

sirbozc51#

根据数据集的不同,有几种方法。下面是一种方法:

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

不必复制+粘贴,您将不得不调整您的具体情况。

oewdyzsn

oewdyzsn2#

在MySQL中,如果找不到行,则可以使用IFNULL返回指定值,即当它返回NULL时,例如

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

您可以在此处看到IFNULL的示例-IFNULL Example

of1yzvn4

of1yzvn43#

我发现的最好的方法是:

SELECT COALESCE(col1, 'defaultValue') col1, COUNT(*) cRows 
FROM table1 
WHERE colx = 'filter';

此查询返回2列:

  • 第一个是在行不存在的情况下使用默认值设置搜索的列的值。
  • 第二列返回表中使用过滤器的行数
11dmarpk

11dmarpk4#

我想补充一下这个+2.5yo的问题,并根据WHERE子句假设Jadeja RJ只想返回四行,而不是整个表(也许表有100,000行,使结果集非常膨胀)。
我不想在SELECT中使用greedy *,所以我将使用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

woobm2wo

woobm2wo5#

使用UNION

SELECT col_x FROM table_x
UNION
SELECT 'default_value';

“default_value”可以是任何数据类型。

mepcadol

mepcadol6#

我写的是这个问题的一个子场景。我发布了一个解决方案,适用于所有有分组查询的人,他们和我一样困惑于如何实现逻辑**,如果带有WHERE子句的查询在CASE 1CASE 2中返回NO ROWS**,则有一行具有默认值。我将向您展示一些过滤超过一行的方法。
希望能有所帮助。

用例1

一种方法是在默认值集从您想要的筛选行中设置之间使用UNION运算符。
您可以执行以下操作:
1.使用默认值创建SELECT语句。
1.然后将1.中的SELECT语句与所需的QUERYUNION(添加一些WHERE子句、GROUP BY或您想要的任何子句)。出于演示目的,我们将查询id列。
1.添加列row_number,其中默认集合为row_number = 0,查询集合为row_number = 1
1.按row_number列以DESC顺序 * 进行排序(以便始终将筛选的行放在第一位 *:order by row_number desc

  • 然后查询整个语句并将结果限制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;

用例2

当然,如果希望从WHERE CLAUSE返回更多行,可以执行查询并对结果执行COUNT(*),以检查是否有ANY行
然后您可以限制计数的行数,它将返回它们:* (+1表示@p_count_rows = 0且您希望返回默认值 *)
请注意,您应该SQL_SELECT_LIMIT设置为您的计数查询(Set SQL_SELECT_LIMIT = @p_counted_rows + 1;)-〉这将在不编写LIMIT CLAUSE的情况下限制确切的行数。完成查询后-将SQL_SELECT_LIMIT设置为DEFAULTSet 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;

希望这对大家都有帮助。

    • 干杯,快乐编程**
a8jjtwal

a8jjtwal7#

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为NOT NULL,则返回值结果。

相关问题