Employees Analyzed
Overall Attrition
High‑Risk Flagged
Annual Savings*
Employees who rated their work‑life balance as "Good" had the highest attrition count (127) — not "Poor" or "Average."
This revealed that attrition isn't always dissatisfaction. Sometimes it's hidden structural pressure — workload creep, stalled careers, unmet expectations — masked by a score that looks fine on paper.
-- Tenure cohort creation
SELECT
EmployeeID,
CASE
WHEN YearsAtCompany <= 2 THEN '0-2'
WHEN YearsAtCompany <= 6 THEN '3-6'
WHEN YearsAtCompany <= 10 THEN '7-10'
WHEN YearsAtCompany <= 15 THEN '10-15'
ELSE '15+'
END AS TenureGroup
FROM Employees;
-- Aggregated view for dashboards
SELECT
Department,
COUNT(*) AS TotalEmployees,
SUM(CASE WHEN Attrition = 'Yes' THEN 1 ELSE 0 END) AS AttritionCount,
AVG(MonthlyIncome) AS AvgMonthlyIncome
FROM EmployeeMaster
GROUP BY Department;
# Overtime vs Satisfaction heatmap – critical insight
pivot = pd.pivot_table(df, values='Attrition_Flag',
index='JobSatisfaction',
columns='OverTime')
sns.heatmap(pivot, annot=True, cmap='Reds')
plt.title("High Risk: Overtime vs Low Satisfaction")
# Correlation analysis
corr = df[['AttritionFlag', 'OverTime', 'JobSatisfaction',
'YearsAtCompany', 'YearsSinceLastPromotion']].corr()
sns.heatmap(corr, annot=True, cmap='coolwarm')
// Risk Score – composite index for proactive flagging
Risk Score =
VAR OvertimeRisk = IF(Employees[OverTime] = "Yes", 0.3, 0)
VAR PromotionRisk = IF(Employees[YearsSinceLastPromotion] > 4, 0.25, 0)
VAR TenureRisk = IF(Employees[YearsAtCompany] <= 2, 0.2, 0)
VAR SatisfactionRisk = IF(Employees[JobSatisfaction] <= 2, 0.15, 0)
RETURN
OvertimeRisk + PromotionRisk + TenureRisk + SatisfactionRisk
// Retention Multiplier – quantifies impact of a factor
Retention Multiplier =
DIVIDE(
CALCULATE([Retention Rate], Employees[OverTime] = "No"),
[Retention Rate]
)
Projected impact: 20–25% reduction in high‑risk attrition → $1M+ annual savings (based on 1.5× salary replacement cost).