我正在构建一个查询来从数据库中搜索多行,例如
SELECT
*
FROM
table1
WHERE col1 = '012311'
OR col1 = '0123631'
OR col1 = '091233'
OR col1 = '092111'
这里返回了前3个值,因为它们存在于表中,但对于最后一个值没有返回任何内容,因为它不在表格中。那么如果查询没有找到该值,我如何在查询中设置默认值?
我正在构建一个查询来从数据库中搜索多行,例如
SELECT
*
FROM
table1
WHERE col1 = '012311'
OR col1 = '0123631'
OR col1 = '091233'
OR col1 = '092111'
这里返回了前3个值,因为它们存在于表中,但对于最后一个值没有返回任何内容,因为它不在表格中。那么如果查询没有找到该值,我如何在查询中设置默认值?
有几种方法,这取决于数据集。以下是其中一种方法:
SELECT *,
IFNULL(
( SELECT col1 FROM table1
WHERE col1 IN ('012311','0123631','091233','092111')
),
'some_value'
) AS my_col1
FROM table1;
并不是必须要复制粘贴,你需要根据你的具体情况进行调整。
在MySQL中,您可以使用IFNULL函数,在没有找到行(即返回NULL)时返回指定的值。例如:
SELECT IFNULL( (SELECT col1 FROM table1 WHERE col1 in (your_list)) ,'default_value_you_want_to_return');
你可以在IFNULL示例中看到示例。
SELECT * FROM
是错误的,无论如何都会减慢整个查询的速度。 - JongosiSELECT COALESCE(col1, 'defaultValue') col1, COUNT(*) cRows
FROM table1
WHERE colx = 'filter';
这个查询返回了2列:
SELECT col_x FROM table_x
UNION
SELECT 'default_value';
'default_value'可以是任何数据类型。
SELECT MAX(TIMESTAMPDIFF(SECOND, created_at, updated_at)) as maxWait FROM my_table UNION select 0
,其中一行为null
,另一行为0
- undefined我想对这个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
。
UNION ALL
而不是只使用UNION
。其他答案都没有起作用。 - VHS我写这篇文章是为了解决一个子场景的问题。我发布了一个适用于所有已分组查询的人的解决方案,以及像我一样想要在CASE 1中实现逻辑在带有WHERE子句的查询返回NO ROWS时具有默认值的行,以及在CASE 2中展示了一些过滤多个行的方法。
希望这能帮到你们。
一种方法是在默认值集合和你想要过滤的行的集合之间使用UNION
运算符。
你可以这样做:
row_number = 0
,查询设置row_number = 1
。order by row_number desc
| 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;
当然,如果你想从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;
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,则返回值结果。
CASE
语句:http://dev.mysql.com/doc/refman/5.0/en/case.html - Jongosi