SQL新手求助:基于内连接计算有/无保修商品的平均配送时间
解决计算有/无保修商品平均配送时间的问题
Hey there! 作为SQL新手碰到这类字段类型不匹配的问题太正常了,我来帮你一步步搞定这个需求~
核心问题梳理
你提到warranty列是非数值类型,值为1或NaN(大概率是字符串'NaN'或者SQL里的NULL),所以不能直接用数值比较来区分保修状态,这很可能是你之前代码报错的原因。另外两个表通过Item_id、Basket_id、seller_id这三个复合主键关联,我们可以利用这个关联来准确匹配数据。
解决方案代码
下面提供两种常用的写法,你可以根据实际表数据情况选择:
写法1:关联两张表分组计算
如果SHIPPING_TABLE里的warranty是权威的保修状态源,我们关联两张表后分组统计:
SELECT -- 区分保修状态 CASE WHEN st.warranty = '1' THEN '有保修' -- 覆盖NULL或字符串'NaN'的情况 WHEN st.warranty IS NULL OR st.warranty = 'NaN' THEN '无保修' ELSE '其他状态' -- 可选:处理意外出现的其他值 END AS warranty_status, -- 计算平均配送时间,AVG会自动忽略delivery_time为NULL的记录 AVG(fc.delivery_time) AS average_delivery_time FROM SHIPPING_TABLE st -- 用复合主键关联,确保数据一一对应 JOIN FIRST_CLASS fc ON st.Item_id = fc.Item_id AND st.Basket_id = fc.Basket_id AND st.seller_id = fc.seller_id -- 按保修状态分组统计 GROUP BY warranty_status;
写法2:直接从FIRST_CLASS统计(如果该表warranty字段可靠)
如果FIRST_CLASS本身已经包含准确的warranty字段,不需要关联表,直接统计更简单:
SELECT CASE WHEN warranty = '1' THEN '有保修' WHEN warranty IS NULL OR warranty = 'NaN' THEN '无保修' ELSE '其他状态' END AS warranty_status, AVG(delivery_time) AS average_delivery_time FROM FIRST_CLASS GROUP BY warranty_status;
你之前代码可能踩的坑
- 类型不匹配错误:比如你写了
warranty = 1(数值比较),但实际warranty是字符串类型,数据库会报类型转换错误,改成warranty = '1'就好。 - 关联错误:没有用全三个复合主键关联,导致数据匹配混乱,出现笛卡尔积或者关联不上的情况。
- NaN处理遗漏:如果
NaN是字符串形式,只判断warranty IS NULL会漏掉这类无保修的记录。
额外小提示
- 如果
delivery_time存在NULL值,AVG函数会自动忽略这些记录,不影响结果准确性。 - 如果需要保留所有SHIPPING_TABLE的记录(哪怕FIRST_CLASS里没有对应配送时间),可以把
JOIN改成LEFT JOIN,此时无匹配的平均时间会显示为NULL。
内容的提问来源于stack exchange,提问作者Harry Brown
相关产品推荐
相关产品推荐

