如果未找到行,则返回默认值
我有以下select语句来获取流的下一个计划项目。如果没有匹配的行,我希望它返回一个默认值。下面是我使用的线:如果未找到行,则返回默认值
SELECT `file` FROM `show`, `schedule`
WHERE `channel` = 1 AND `start_time` <= UNIX_TIMESTAMP()
AND `start_time` > UNIX_TIMESTAMP()-1800 AND `show`.`id` = `schedule`.`file`
ORDER BY `start_time` DESC LIMIT 1
这应该抓住最近预约内容,但如果查询前年长超过30分钟没有。但是,如果用户没有计划任何事情,我需要一个默认值,以便在流上实际播放某些内容。我已经试过如下:
SELECT COALESCE(`file`, 'default.webm') FROM `show`, `schedule`...
和:
SELECT IFNULL(`file`, 'default.webm') FROM `show`, `schedule`
然而,如果没有行被发现总是返回一个空的结果。我怎样才能返回一个默认值呢?
一种方式做到这一点
SELECT IFNULL(MIN(`file`), 'default.webm') `file`
FROM `show`, `schedule`
WHERE `channel` = 1 AND `start_time` <= UNIX_TIMESTAMP()
AND `start_time` > UNIX_TIMESTAMP()-1800 AND `show`.`id` = `schedule`.`file`
ORDER BY `start_time` DESC LIMIT 1
既然你只返回一行,您可以使用一个聚合函数,在这种情况下MIN()
,确保,如果选择没有记录,你会得到NULL
。然后IFNULL()
或COALESCE()
将完成其工作。
要处理更多种情况,您需要一些条件逻辑。这仅仅是在MySQL存储过程中可用,因此你需要在过程中包装该代码,并称之为:
if exists (
SELECT `file` FROM `show`, `schedule`
WHERE `channel` = 1 AND `start_time` <= UNIX_TIMESTAMP()
AND `start_time` > UNIX_TIMESTAMP()-1800 AND `show`.`id` = `schedule`.`file`
) then
SELECT `file` FROM `show`, `schedule`
WHERE `channel` = 1 AND `start_time` <= UNIX_TIMESTAMP()
AND `start_time` > UNIX_TIMESTAMP()-1800 AND `show`.`id` = `schedule`.`file`
ORDER BY `start_time` DESC LIMIT 1
; else
select `DefaultValue` as `file`
; end if
对于那些结果只有一行预期的情况下,只需使用UNION
用硬编码值( s)在第二个SELECT
子句中具有与原始SELECT相同的列数。
对于OP:
(SELECT `file` FROM `show`, `schedule`
WHERE `channel` = 1 AND `start_time` <= UNIX_TIMESTAMP()
AND `start_time` > UNIX_TIMESTAMP()-1800 AND `show`.`id` = `schedule`.`file`
ORDER BY `start_time` DESC LIMIT 1) UNION (SELECT 'default.webm') LIMIT 1;
除非任何语法错误,结果集将成为移动一行与所谓file
一列。
作为更一般的例子:
(SELECT Col1,Col2,Col3 FROM ExampleTable WHERE ID='1234')
UNION (SELECT 'Def Val','none','') LIMIT 1;
在任一情况:
如果没有在所述第一SELECT发现行,结果集将被填充有来自第二个SELECT的值。
如果在第一个SELECT中找到一行,则会在结果集中提供第一个SELECT值,并省略第二个SELECT值。
*你,如果你想从第一个SELECT使用相同的列(以相同的顺序)没有列名/别名分配给第二选择值。
* UNION不要求来自两个联合查询的列名是相同的,事实上,如果它有助于您的情况,您可以将不同的列名分配给第二个SELECT查询。 (您的结果集处理代码将需要适应这些列命名差异。)
(SELECT Col1,Col2,Col3 FROM ExampleTable WHERE ID='1234')
UNION (SELECT 'Def Val' AS `Fallback1`,'none' AS `Fallback2`,'' AS `Fallback3`) LIMIT 1;
我的意见是,这是很容易阅读,似乎并不像征税查询。
这对我来说非常好。我需要用一个谓词来进行聚集('MAX'),如果没有与谓词相匹配的行,我就不会返回行。现在我得到默认回来。 – Rob 2017-01-04 18:39:33
辉煌的东西!但是,如何将这个概念应用于返回多行而不是一个查询的查询? – Vectoria 2015-07-16 13:47:17
这不是一个很好的解决方案,正如Tomas在下面解释的那样(除非您查询主键值)。 – Pierre 2015-10-18 07:39:33