Как посчитать attrition by tenure в SQL
Содержание:
Зачем attrition by tenure
Не все months увольнения одинаковы. Юзер уходящий в month 3 (плохой onboarding) и month 24 (growth opportunity) — разные проблемы. Attrition by tenure показывает, где «узкие места» в employee lifecycle. Standard: peak attrition обычно в month 6-12 (honeymoon ends) и month 18-24 (vesting milestone, рынок зовёт).
Tenure buckets
- 0-90 days — first quarter
- 91-180 days — second quarter
- 6-12 months
- 1-2 years
- 2-3 years
- 3+ years
Attrition в SQL
WITH leavers AS (
SELECT
employee_id,
EXTRACT(EPOCH FROM (termination_date - hire_date)) / 86400 AS tenure_days
FROM employees
WHERE termination_date IS NOT NULL
AND termination_date >= CURRENT_DATE - INTERVAL '24 months'
)
SELECT
CASE
WHEN tenure_days <= 90 THEN '0-3m'
WHEN tenure_days <= 180 THEN '3-6m'
WHEN tenure_days <= 365 THEN '6-12m'
WHEN tenure_days <= 730 THEN '1-2y'
ELSE '2+y'
END AS tenure_bucket,
COUNT(*) AS leavers
FROM leavers
GROUP BY 1
ORDER BY MIN(tenure_days);Спайк в bucket '6-12m' — onboarding не закончился к 6 мес. Спайк '1-2y' — vesting / promotion stalled.
Retention curve
Kaplan-Meier-like для employees:
WITH employee_status AS (
SELECT
employee_id,
hire_date,
COALESCE(termination_date, CURRENT_DATE) AS observed_until,
termination_date IS NOT NULL AS churned
FROM employees
WHERE hire_date >= '2022-01-01'
),
month_buckets AS (
SELECT
FLOOR(EXTRACT(EPOCH FROM (observed_until - hire_date)) / 86400 / 30)::INT AS month_tenure,
churned
FROM employee_status
),
risk_set AS (
SELECT
month_tenure,
COUNT(*) FILTER (WHERE churned) AS leavers,
SUM(COUNT(*)) OVER (ORDER BY month_tenure DESC) AS at_risk
FROM month_buckets
GROUP BY month_tenure
)
SELECT
month_tenure,
at_risk,
leavers,
EXP(SUM(LN(1 - leavers::NUMERIC / NULLIF(at_risk, 0))) OVER (ORDER BY month_tenure)) AS retention
FROM risk_set
WHERE at_risk > 0
ORDER BY month_tenure;Survival curve до 36+ месяцев. После 24 mo обычно plato (loyal core).
Сравнение cohort
SELECT
DATE_TRUNC('year', hire_date)::DATE AS hire_year,
COUNT(*) FILTER (WHERE tenure_days >= 365) AS still_at_1y,
COUNT(*) AS cohort_size,
COUNT(*) FILTER (WHERE tenure_days >= 365) * 100.0 / COUNT(*) AS retention_1y_pct
FROM employees
WHERE hire_date < CURRENT_DATE - INTERVAL '1 year'
GROUP BY DATE_TRUNC('year', hire_date)
ORDER BY hire_year;Год-к-году retention позволяет видеть, улучшается ли культура.
Частые ошибки
Ошибка 1. Не учитывать censoring. Сотрудник работает 6 месяцев — это не «retained year 1», это «not yet». Survival analysis.
Ошибка 2. Tenure-агрегаты на маленьких cohort. Если 2024-цикл — 10 человек, 30% attrition = 3 человека. Шумно.
Ошибка 3. Игнорировать involuntary. Layoff в month 6 — это не early voluntary attrition, а сокращение. Фильтруйте по типу.
Ошибка 4. One-size cohort. Engineering vs Sales attrition разный. Сегментируйте.
Ошибка 5. Считать только voluntary как attrition. Total attrition вместе с laid-off тоже обоснован. Зависит от целей метрики.
Связанные темы
- Как посчитать employee turnover в SQL
- Как посчитать customer tenure в SQL
- Как посчитать Kaplan-Meier в SQL
- Как посчитать survival rate в SQL
FAQ
Когда peak attrition?
Month 3-6 (плохой fit) и month 12-24 (vesting, opportunity).
90-day attrition какой норма?
5-10% для tech. Свыше 15% = плохой onboarding или ошибка в hiring.
Можно ли predict attrition?
Yes — модели на features (engagement, manager, comp). Survival regression.
Как лечить early attrition?
Better onboarding, mentor program, 30/60/90 day check-ins.
Late attrition?
Career path, comp review, retention bonus.