You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL查询返回0结果问题排查(涉及CONCAT与CAST函数)

排查MySQL查询返回0结果的问题

让我从语法和逻辑两方面帮你分析这个问题:

首先是语法错误

MySQL里用CAST()转换为字符串类型时,正确的类型关键字是CHAR,而不是你写的VARCHAR。你的代码里CAST(r.any - 1 as varchar(4))不符合MySQL语法规范,应该改成CAST(r.any - 1 AS CHAR(4))(或者简化成CAST(r.any -1 AS CHAR))。虽然部分MySQL版本可能会兼容这个错误,但这是第一个需要修正的点,否则可能导致条件判断异常。

核心问题:逻辑冲突导致无匹配行

你添加的那段代码和原有的p.any_id条件存在逻辑冲突,这才是查询返回0结果的关键原因:

原有的p.any_id固定限制

(p.any_id = '2017-2018' or p.any_id = '2016-2017')

这把p.any_id的取值范围固定在了两个特定字符串上。

新添加的动态匹配条件

((r.mes < 9 and p.any_id = CONCAT(CAST(r.any - 1 as CHAR(4)),"-",CAST(r.any as CHAR(4)))) 
or 
(r.mes >= 9 and p.any_id = CONCAT(CAST(r.any as CHAR(4)),"-",CAST(r.any + 1 as CHAR(4)))))

我们拆解这个逻辑:

  • 当r.mes <9时,动态生成的p.any_id格式是(年份-1)-年份,比如2017年的话就是2016-2017,2018年的话是2017-2018
  • 当r.mes >=9时,动态生成的格式是年份-(年份+1),比如2017年是2017-2018,2018年是2018-2019

同时,你原有的时间范围条件还藏着冗余无效的逻辑:

((r.any = 2017 and r.mes = 1) or (r.any > 2017 and r.any < 2018) or (r.any = 2018 and r.mes = 1) or (2017 != 2018 and ((r.any = 2017 and r.mes > 1) or (r.any = 2018 and r.mes < 1))))
  • r.any >2017 and r.any <2018永远为假,因为年份是整数,不存在中间值
  • r.any=2018 and r.mes <1也永远为假,月份的最小值是1

简化后有效的时间范围其实是:2017全年 + 2018年1月,也就是(r.any =2017) OR (r.any=2018 AND r.mes=1)。

结合起来看:只有当动态生成的p.any_id恰好等于2016-2017或2017-2018时,才会有匹配的行。如果你的数据里没有同时满足这些交叉条件的记录,就会返回0结果。

修复建议

  1. 修正CAST语法:把所有varchar(4)改成CHAR(4)
  2. 简化时间条件:替换冗余的时间判断,让逻辑更清晰
  3. 验证条件交集:先单独查询看看有没有行同时满足p.any_id的固定值和动态生成值,比如执行下面的测试语句:
SELECT 
    r.any, r.mes,
    CONCAT(CAST(r.any -1 AS CHAR(4)),"-",CAST(r.any AS CHAR(4))) as expected_id1,
    CONCAT(CAST(r.any AS CHAR(4)),"-",CAST(r.any +1 AS CHAR(4))) as expected_id2,
    p.any_id
FROM report r
JOIN persona p ON r.usuari_upc = p.persona_id 
WHERE (r.any = 2017 OR (r.any =2018 AND r.mes=1))
AND (p.any_id = '2017-2018' OR p.any_id = '2016-2017')

如果查询结果里没有p.any_id等于expected_id1或expected_id2的行,说明这两组条件确实没有交集,需要根据你的业务需求调整:要么放宽p.any_id的固定值限制,要么修改动态匹配的逻辑。

最后附上修正语法和简化后的完整查询示例:

SELECT 
    p.seccio_id as seccio, 
    COUNT(DISTINCT r.usuari_upc) as usuaris, 
    SUM(r.preu) as preu 
FROM report r
JOIN persona p ON r.usuari_upc = p.persona_id 
WHERE 
    -- 简化后的有效时间范围
    (r.any = 2017 OR (r.any = 2018 AND r.mes = 1))
    AND (p.any_id = '2017-2018' OR p.any_id = '2016-2017')
    AND (
        (r.mes < 9 AND p.any_id = CONCAT(CAST(r.any - 1 AS CHAR(4)),"-",CAST(r.any AS CHAR(4)))) 
        OR 
        (r.mes >= 9 AND p.any_id = CONCAT(CAST(r.any AS CHAR(4)),"-",CAST(r.any + 1 AS CHAR(4))))
    )
GROUP BY p.seccio_id 
ORDER BY p.seccio_id 

内容的提问来源于stack exchange,提问作者Manelicus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:58:44