使用Sqlite3(Python)计算员工入职平均年龄遇问题求助
问题分析与修正方案
核心问题:工龄计算完全错误
你当前计算工龄的CASE语句逻辑完全颠倒:strftime('%Y', date(HireDate)) - strftime('%Y', date('now'))是用入职年份减去当前年份,结果必然是负数,而且完全没考虑月份、日期的差异,根本得不到正确的工龄数值。这直接导致你用年龄减工龄时,结果完全不符合预期。
更高效的思路:直接计算入职时的年龄
其实不用绕弯子先算当前年龄和工龄再相减,直接计算员工入职当天的年龄更准确,逻辑和你计算当前年龄的方式一致,只是把date('now')换成HireDate即可。之后再对所有入职年龄取平均值并转成整数。
修正后的最终查询(直接计算入职平均年龄)
SELECT ROUND(AVG( CASE WHEN strftime('%m', HireDate) > strftime('%m', BirthDate) THEN strftime('%Y', HireDate) - strftime('%Y', BirthDate) WHEN strftime('%m', HireDate) = strftime('%m', BirthDate) THEN CASE WHEN strftime('%d', HireDate) >= strftime('%d', BirthDate) THEN strftime('%Y', HireDate) - strftime('%Y', BirthDate) ELSE strftime('%Y', HireDate) - strftime('%Y', BirthDate) - 1 END ELSE strftime('%Y', HireDate) - strftime('%Y', BirthDate) - 1 END )) AS average_hire_age FROM Employee;
ROUND()用于将平均值四舍五入为整数,如果需要直接截断小数取整,换成CAST(AVG(...) AS INTEGER)即可。
若需保留原字段(当前年龄、工龄)的修正版
如果你一定要保留当前年龄、工龄的展示,再计算入职年龄,需要先修正工龄的计算逻辑,再做差值:
SELECT HireDate, -- 原当前年龄计算逻辑保留 CASE WHEN strftime('%m', date('now')) > strftime('%m', date(BirthDate)) THEN strftime('%Y', date('now')) - strftime('%Y', date(BirthDate)) WHEN strftime('%m', date('now')) = strftime('%m', date(BirthDate)) THEN CASE WHEN strftime('%d', date('now')) >= strftime('%d', date(BirthDate)) THEN strftime('%Y', date('now')) - strftime('%Y', date(BirthDate)) ELSE strftime('%Y', date('now')) - strftime('%Y', date(BirthDate)) - 1 END ELSE strftime('%Y', date('now')) - strftime('%Y', date(BirthDate)) - 1 END AS age, -- 修正后的工龄计算 CASE WHEN strftime('%m', date('now')) > strftime('%m', date(HireDate)) THEN strftime('%Y', date('now')) - strftime('%Y', date(HireDate)) WHEN strftime('%m', date('now')) = strftime('%m', date(HireDate)) THEN CASE WHEN strftime('%d', date('now')) >= strftime('%d', date(HireDate)) THEN strftime('%Y', date('now')) - strftime('%Y', date(HireDate)) ELSE strftime('%Y', date('now')) - strftime('%Y', date(HireDate)) - 1 END ELSE strftime('%Y', date('now')) - strftime('%Y', date(HireDate)) - 1 END AS yw, -- 入职时年龄 = 当前年龄 - 工龄 ( CASE WHEN strftime('%m', date('now')) > strftime('%m', date(BirthDate)) THEN strftime('%Y', date('now')) - strftime('%Y', date(BirthDate)) WHEN strftime('%m', date('now')) = strftime('%m', date(BirthDate)) THEN CASE WHEN strftime('%d', date('now')) >= strftime('%d', date(BirthDate)) THEN strftime('%Y', date('now')) - strftime('%Y', date(BirthDate)) ELSE strftime('%Y', date('now')) - strftime('%Y', date(BirthDate)) - 1 END ELSE strftime('%Y', date('now')) - strftime('%Y', date(BirthDate)) - 1 END ) - ( CASE WHEN strftime('%m', date('now')) > strftime('%m', date(HireDate)) THEN strftime('%Y', date('now')) - strftime('%Y', date(HireDate)) WHEN strftime('%m', date('now')) = strftime('%m', date(HireDate)) THEN CASE WHEN strftime('%d', date('now')) >= strftime('%d', date(HireDate)) THEN strftime('%Y', date('now')) - strftime('%Y', date(HireDate)) ELSE strftime('%Y', date('now')) - strftime('%Y', date(HireDate)) - 1 END ELSE strftime('%Y', date('now')) - strftime('%Y', date(HireDate)) - 1 END ) AS hire_age FROM Employee;
内容的提问来源于stack exchange,提问作者Jacob
相关产品推荐
相关产品推荐

