SQL查询可享老年折扣患者返回空集的原因及写法咨询
原SQL语句的错误点
- 语法使用错误:
AS是SQL中用于给字段、计算结果定义别名的关键字,仅允许出现在SELECT子句的字段声明段,不能写在WHERE过滤子句中。SQL的执行顺序中,WHERE过滤阶段早于SELECT字段别名生成阶段,该写法本身不符合SQL语法规范。 - 年龄计算逻辑错误:
datediff函数默认返回两个日期之间的天数差值,直接将天数差值和75做阈值判断,完全不符合“年龄按年份计算”的业务逻辑。 - 函数传参顺序错误:主流数据库的
datediff类日期差函数均要求传入参数顺序为「晚的日期在前、早的日期在后」,原语句将出生日期pdob(更早的日期)放在第一位,统计基准日'2022-06-11'(更晚的日期)放在第二位,计算得到的差值为负数。
查询返回空结果的原因
- 若数据库对语法错误做静默容错处理,会直接将
WHERE后的非法逻辑判定为无匹配值,直接返回空集; - 即便语法被异常解析,传参顺序错误导致日期差返回负数,永远无法满足
>=75的判断条件,自然匹配不到任何记录; - 即便修正参数顺序,天数差和75年的判断阈值完全不匹配,就算返回数据也完全不符合老年折扣的业务筛选要求。
正确查询写法
业务筛选规则为:以2022年6月11日为基准日,筛选年满75周岁及以上的患者。年龄计算需规避“未到生日就虚增一岁”的误差,不同数据库的日期函数写法略有差异:
核心计算逻辑:以完整年份为单位计算出生日期到基准日的时间差,需校验基准日是否已超过对应年份的生日日期。
MySQL环境可直接使用TIMESTAMPDIFF函数(自动处理生日校验,返回完整年份差):
SELECT * FROM patient WHERE TIMESTAMPDIFF(YEAR, pdob, '2022-06-11') >= 75;
SQL Server环境写法:
SELECT * FROM patient WHERE DATEDIFF(YEAR, pdob, '2022-06-11') - CASE WHEN DATEADD(YEAR, DATEDIFF(YEAR, pdob, '2022-06-11'), pdob) > '2022-06-11' THEN 1 ELSE 0 END >= 75;
如果需要在结果中展示age年龄字段,可通过子查询预先计算别名后再过滤,不要在WHERE子句中直接使用AS定义别名:
SELECT * FROM ( SELECT *, TIMESTAMPDIFF(YEAR, pdob, '2022-06-11') AS age FROM patient ) AS patient_with_age WHERE age >= 75;
内容的提问来源于stack exchange,提问作者Rahul Srivastava
相关产品推荐
相关产品推荐

