Qml+JS查询数据库无匹配行时如何返回100?
解决无匹配数据时返回100的SQL查询问题
我来帮你分析下问题根源,再给出切实可行的解决方案:
为什么你的两种写法都报错?
第一种写法:
IFNULL((CASE ... ELSE 100 END),100)
核心问题是:当没有匹配行时,整个查询结果集是空的,不存在任何行数据,IFNULL根本没有生效的对象。Qml尝试读取pourcent属性时,因为结果是undefined,所以抛出了Cannot read property 'pourcent' of undefined的错误。第二种写法:
IFNULL(SELECT (CASE ... ELSE 100 END) ,100)
这是明显的语法错误——IFNULL的第一个参数如果是子查询,必须用括号包裹,但就算修正了括号,子查询在无匹配时返回的是空结果集而非NULL,所以IFNULL依然无法触发,反而先因为语法错误报错。
两种可行的解决方案
方案1:用UNION ALL添加默认行(推荐,保留原字段信息)
通过UNION ALL拼接一个默认结果行,再通过排序确保原查询的结果优先返回,无匹配时则返回默认行:
SELECT CASE WHEN pourcenthour < pourcentcycle AND pourcenthour < pourcentmonth THEN pourcenthour WHEN pourcentcycle < pourcenthour AND pourcentcycle < pourcentmonth THEN pourcentcycle WHEN pourcentmonth < pourcenthour AND pourcentmonth < pourcentcycle THEN pourcentmonth ELSE 100 END AS pourcent, ata, immatriculation, 1 AS priority -- 标记原查询结果的优先级 FROM part_log WHERE removed = "false" AND immatriculation = ? AND ata = ? UNION ALL SELECT 100 AS pourcent, NULL AS ata, NULL AS immatriculation, 2 AS priority -- 标记默认行的优先级 ORDER BY priority ASC, pourcent DESC -- 优先取原查询结果 LIMIT 1
- 优势:如果有匹配行,会返回原数据的
ata和immatriculation;无匹配时返回pourcent=100,其他字段为NULL。 - 注意:
UNION ALL要求两个结果集的列数、字段类型完全匹配,所以默认行的ata和immatriculation设为NULL(和原字段类型兼容)。
方案2:用聚合函数强制返回一行
利用聚合函数(如MAX)即使无匹配行也会返回NULL的特性,结合IFNULL替换为100:
SELECT IFNULL(MAX( CASE WHEN pourcenthour < pourcentcycle AND pourcenthour < pourcentmonth THEN pourcenthour WHEN pourcentcycle < pourcenthour AND pourcentcycle < pourcentmonth THEN pourcentcycle WHEN pourcentmonth < pourcenthour AND pourcentmonth < pourcentcycle THEN pourcentmonth ELSE 100 END ), 100) AS pourcent, MAX(ata) AS ata, MAX(immatriculation) AS immatriculation FROM part_log WHERE removed = "false" AND immatriculation = ? AND ata = ?
- 原理:聚合查询无论是否有匹配行,都会返回一行结果。有匹配行时,
MAX会取唯一行的对应值;无匹配时,MAX返回NULL,被IFNULL替换为100。 - 注意:如果原查询有多个匹配行(虽然你加了
LIMIT 1),这里的MAX和你原逻辑的ORDER BY pourcent DESC LIMIT 1效果一致。
内容的提问来源于stack exchange,提问作者Philippe
相关产品推荐
相关产品推荐

