GROUP BY и HAVING: считать и отсеивать группы

Одиночная улика молчит. Она говорит, когда повторяется. Не «заходил ли он в лавку» — а «сколько раз он туда заходил за месяц». Вопрос меняется с «кто» на «сколько раз».

GROUP BY сворачивает строки в группы по общему признаку, COUNT считает, сколько их в каждой.

SELECT person_id, COUNT(*) AS visits
FROM receipts
GROUP BY person_id;
person_idvisits
1041
2012
30711

Один визит или одиннадцать — где проходит граница?

Один визит — шум. Одиннадцать за месяц в лавку, где сам ничего не покупал, — уже узор. Отсечь редких помогает не WHERE, а HAVING: WHERE режет строки до того, как они сгруппированы, HAVING — уже сами группы, после подсчёта.

SELECT person_id, COUNT(*) AS visits
FROM receipts
GROUP BY person_id
HAVING COUNT(*) >= 5;
«WHERE спрашивает про человека. HAVING спрашивает про его привычку.»

CASE считает по условию прямо внутри одного прохода — не три отдельных запроса, а один срез сразу на несколько корзин.

SELECT person_id,
  SUM(CASE WHEN hour < 12 THEN 1 ELSE 0 END) AS утром,
  SUM(CASE WHEN hour >= 18 THEN 1 ELSE 0 END) AS вечером
FROM receipts
GROUP BY person_id;

Почему в отчёте сходится не всё?

Капкан здесь тихий и въедливый: COUNT(колонка) считает не строки, а непустые значения этой колонки. Если у части визитов не заполнена графа «сумма», COUNT(сумма) их попросту не досчитает — и «одиннадцать визитов» на бумаге превратятся в «семь», хотя человек приходил все одиннадцать раз.

COUNT(*)      -- все строки, включая пустые графы
COUNT(amount) -- только те, где сумма вообще указана
«Никто не солгал в отчёте. Отчёт просто не считал то, что не было записано. Это не ложь. Это дыра — и она страшнее лжи, потому что выглядит честно.»

На работе так ловят фрод: не одна подозрительная сделка, а частота — кто повторяет один и тот же манёвр слишком часто для случайности. Одна встреча ничего не значит. Узор — значит всегда.

Одиночная улика молчит и в архиве. Откройте дело, где виновного выдаёт не поступок, а его повторяемость.

$0
тащи карточки за верхнюю кромку · «+ стикер» · «🧵 нить» — клик по двум

ЛОТОК УЛИК

во вкладке SQL найди подозреваемых и жми «+ доска»

НА ПРОВЕРКУ

теории из «Заметок» отправляются сюда — подтверди на доске или удали
Ctrl+Enter · «+ доска» на строке — выбрать поля и перенестипиши запрос, я подожду
Результат появится здесь.

Картотека

Заметки

Факты

Теории на проверку

Подсказки

◆ РЕЖИМ АРХИВАРИУСАуправление картотекой дел · не виден игроку