Как посчитать корреляцию в SQL
Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.
Зачем это нужно
Корреляция — базовая статистическая метрика, показывающая связь двух числовых переменных. Чаще всего аналитика просят: «связаны ли revenue и session length?», «коррелирует ли frequency покупок с LTV?». Можно выгрузить данные в pandas и посчитать, но SQL позволяет делать это прямо в запросе / дашборде.
На собесе часто спрашивают: «как посчитать корреляцию в SQL»? Postgres, SQL Server и ClickHouse имеют встроенную CORR(). MySQL — нет, нужен manual расчёт. Знание обоих вариантов — middle уровень.
В статье:
- CORR() в Postgres / SQL Server / ClickHouse
- Manual формула в MySQL
- Correlation matrix для нескольких колонок
- Интерпретация (от -1 до 1)
- Когда использовать нельзя
1. CORR в Postgres / SQL Server / BigQuery
SELECT CORR(revenue, session_length) AS correlation
FROM user_stats;Возвращает число от -1 до 1.
С фильтром
SELECT CORR(revenue, session_length) AS correlation
FROM user_stats
WHERE revenue IS NOT NULL
AND session_length IS NOT NULL;2. В ClickHouse
SELECT corr(revenue, session_length) FROM user_stats;Нижний регистр. Быстрый на больших таблицах.
3. В MySQL (manual)
MySQL не имеет CORR. Считаем формулу Пирсона:
SELECT
(n * sum_xy - sum_x * sum_y) /
SQRT((n * sum_x2 - sum_x * sum_x) * (n * sum_y2 - sum_y * sum_y)) AS correlation
FROM (
SELECT
COUNT(*) AS n,
SUM(revenue) AS sum_x,
SUM(session_length) AS sum_y,
SUM(revenue * session_length) AS sum_xy,
SUM(revenue * revenue) AS sum_x2,
SUM(session_length * session_length) AS sum_y2
FROM user_stats
) t;4. По сегментам
SELECT
country,
CORR(revenue, session_length) AS correlation
FROM user_stats
GROUP BY country
ORDER BY correlation DESC;5. Correlation matrix (несколько пар)
SELECT
'revenue vs sessions' AS pair,
CORR(revenue, session_length) AS corr
UNION ALL
SELECT 'revenue vs age', CORR(revenue, age)
UNION ALL
SELECT 'sessions vs age', CORR(session_length, age);Или через dynamic pivot (сложнее, но чище).
6. По когортам
SELECT
DATE_TRUNC('month', signup_at) AS cohort,
CORR(ltv, referrals_count) AS correlation
FROM user_stats
GROUP BY 1
ORDER BY 1;Полезно — связь между метриками меняется во времени.
7. Spearman vs Pearson
CORR в SQL даёт Pearson (линейная связь).
Для Spearman (монотонная, ранговая) нужно сначала преобразовать в ранги:
WITH ranks AS (
SELECT
RANK() OVER (ORDER BY revenue) AS rank_x,
RANK() OVER (ORDER BY session_length) AS rank_y
FROM user_stats
)
SELECT CORR(rank_x, rank_y) AS spearman_correlation
FROM ranks;8. Интерпретация
| Значение | Связь |
|---|---|
| 0.9 - 1.0 | очень сильная положительная |
| 0.7 - 0.9 | сильная положительная |
| 0.4 - 0.7 | умеренная положительная |
| 0.1 - 0.4 | слабая положительная |
| -0.1 - 0.1 | нет связи |
| -0.4 - -0.1 | слабая отрицательная |
| -0.7 - -0.4 | умеренная отрицательная |
| и т.д. |
НО: correlation ≠ causation. Связаны ≠ одно причина другого.
9. Statistical significance
Для большого N почти любая correlation будет значима. Проверяйте p-value:
-- для N = 10000, correlation 0.02 будет p<0.05, но практически бессмысленнаПрименяйте common sense.
10. Ограничения
Нелинейные связи
Pearson измеряет только линейную. Y = X² — correlation ≈ 0, но связь идеальная.
Выбросы
Один outlier может изменить correlation на 0.3-0.5. Обрабатывайте.
Small sample
На N < 30 correlation нестабильна.
Частые ошибки
1. Использовать CORR для категорий
CORR(gender, revenue) — не работает. Gender не число. Нужны specific тесты (t-test, chi-square).
2. Correlation = causation
Высокая correlation → надо A/B или causal analysis для причинности.
3. Single number без plots
Без scatter plot correlation обманчива. Anscombe's quartet: 4 набора с correlation 0.82, выглядящие совершенно разно.
4. MySQL без готовой функции
Можно забыть. Знайте manual формулу.
Связанные темы
FAQ
CORR в ClickHouse для миллиардов?
Быстрый. Специализированный engine.
Можно ли correlation в aggregated window?
Да, CORR — oconная функция (в Postgres): CORR(x, y) OVER (...).
Как экспортировать в pandas для глубокого анализа?
pd.read_sql + df.corr() для matrix.
Sign значимости?
Python: scipy.stats.pearsonr(x, y) возвращает и corr, и p-value.
Тренируйте SQL — откройте тренажёр с 1500+ вопросами для собесов.