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

按特定客户时段统计准时交付率的SQL查询优化需求

解决SQL准时交付率计算问题

嘿,我来帮你搞定这个查询的修改需求!你的现有查询已经有了基础,但漏掉了几个关键细节——比如服务有效期的判断,还有准时交付率的计算逻辑,我来一步步给你修正:

首先,先看修改后的完整查询:

SELECT 
    i.NumCptCli, 
    i.nomVille, 
    i.heureImp, 
    COUNT(*) AS TotalLivs,
    ROUND(
        (SUM(CASE WHEN l.heureLiv <= i.heureImp THEN 1 ELSE 0 END) * 100.0) / COUNT(*),
        2
    ) AS livsAlheure
FROM LIVRAISON l
INNER JOIN IMPERATIF i 
    ON l.NumCptClient = i.NumCptCli 
    AND l.nomVille = i.nomVille
    AND l.DateLiv BETWEEN i.dateDebImp AND i.dateFinImp
GROUP BY i.NumCptCli, i.nomVille, i.heureImp;

接下来给你拆解每个修改点的原因:

  • 替换隐式JOIN为显式INNER JOIN:
    原来的NATURAL JOIN虽然能匹配同名列,但风险很高(如果后续表加了新的同名列会出问题),而且你之前的需求里明确要求交付日期必须在服务有效期内,这个条件在原查询里完全没加!所以我把JOIN条件明确写出来,加上l.DateLiv BETWEEN i.dateDebImp AND i.dateFinImp,确保只统计属于增值服务范畴的交付记录。

  • 计算准时交付率livsAlheure:
    用SUM(CASE WHEN l.heureLiv <= i.heureImp THEN 1 ELSE 0 END)统计所有准时交付的数量,乘以100.0把结果转成百分比格式(用100.0而不是100是为了避免整数除法导致的精度丢失),再除以总交付数COUNT(*),最后用ROUND(..., 2)保留两位小数,和你给出的示例格式一致。如果需要支持一位小数(比如示例里的95.2),可以把ROUND的第二个参数改成1。

  • 完善GROUP BY子句:
    原查询的GROUP BY只包含了NumCptCli和nomVille,但SELECT里还返回了heureImp,在大多数严格的SQL模式下(比如MySQL的ONLY_FULL_GROUP_BY)会报错,所以必须把heureImp也加入GROUP BY——毕竟每个客户-城镇组合的限时服务时间应该是唯一的,这样做既符合SQL规范,也避免潜在的逻辑问题。

  • 自动排除无交付的服务组合:
    因为用了INNER JOIN,只有当IMPERATIF里的服务组合在LIVRAISON中有符合条件的交付记录时,才会被纳入结果集,正好满足你“排除无对应交付记录的服务组合”的需求,不需要额外加过滤条件。

如果你的数据库支持窗口函数或者其他聚合语法,也可以用更简洁的写法计算交付率,效果完全一致:

-- 简化版的准时交付率计算
AVG(CASE WHEN l.heureLiv <= i.heureImp THEN 100.0 ELSE 0 END) AS livsAlheure

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:25:52