TGViewer
Data Science. SQL hub Data Science. SQL hub @sqlhub · 36K subscribers
Post #1875 5.4K
🛢️ SQL-задача с подвохом: GROUP BY и скрытая ловушка

Условие:

Есть таблица orders:

| id | customer_id | amount | status |
|-----|-------------|--------|-----------|
| 1 | 101 | 200 | completed |
| 2 | 102 | 150 | NULL |
| 3 | 101 | 300 | completed |
| 4 | 103 | NULL | completed |
| 5 | 102 | 100 | completed |
| 6 | 101 | 250 | NULL |

Задача: найти всех клиентов, у которых сумма заказов больше 500.

Ты пишешь запрос:


SELECT customer_id, SUM(amount) as total
FROM orders
GROUP BY customer_id
HAVING SUM(amount) > 500;


❓ Вопрос:
Какие клиенты вернутся? Есть ли тут подвох? Что произойдёт с заказами, где amount или status — NULL?

🔍 Подвох:

На первый взгляд запрос правильный: мы группируем по клиентам и суммируем их заказы. Но вот критичные моменты:

1️⃣ Что происходит с NULL в `amount`?

В SQL агрегатные функции (например, SUM) игнорируют NULL значения. Это значит:

- Заказ id=4 (`amount = NULL`) не участвует в суммировании.
- Заказ id=6 (`amount = 250`) участвует, потому что amount не NULL.

2️⃣ Считаем по каждому клиенту:

- customer_id=101:
- id=1: 200
- id=3: 300
- id=6: 250
Итого: 200 + 300 + 250 = 750

- customer_id=102:
- id=2: 150
- id=5: 100
Итого: 150 + 100 = 250

- customer_id=103:
- id=4: NULL (игнорируется)
Итого: 0

3️⃣ Кто попадёт в результат:

Только customer_id=101 (с суммой 750 > 500).

---

✅ Результат:

| customer_id | total |
|-------------|--------|
| 101 | 750 |

---

💥 Подвох #2:

Допустим ты случайно написал:


HAVING SUM(amount) IS NOT NULL AND SUM(amount) > 500;


Кажется логичным? А вот нет: SUM всегда возвращает 0 (не NULL), даже если у клиента нет заказов с ненулевой суммой.

➡️ Даже клиент с только NULL значениями (например, customer_id=103) получит SUM(amount) = 0, а не NULL.

Это частая ловушка:
COUNT, SUM, AVG игнорируют NULL внутри, но результат НЕ NULL (обычно 0 или NULL в зависимости от агрегата).

---

🛠 Что ещё важно:

• Если хочешь учитывать только выполненные заказы (status = 'completed'), нужно добавить:


WHERE status = 'completed'


⚠️ Не пиши условие в HAVING для фильтрации строк — лучше фильтровать через WHERE до группировки.

✅ Вывод:

- ✅ Агрегатные функции типа SUM игнорируют NULL внутри группы.
- ✅ SUM возвращает 0, даже если все значения NULL (НЕ NULL, как думают многие).
- ✅ HAVING применяется ПОСЛЕ группировки, а WHERE — ДО.
- ✅ Ошибки часто возникают, если условие на фильтр пишут в HAVING вместо WHERE.

💡 Бонус-вопрос:
Что будет, если заменить SUM(amount) на COUNT(amount) в SELECT и HAVING? И как это повлияет на клиентов с NULL значениями?

@sqlhub
  • 🔥 17
  • 👍 7
  • ❤ 6
More from @sqlhub
  1. Sep 27, 2026💀 Claude Code за 103 секунды удалил более 48 тысяч файлов Пользователь Claude Code сообщи…
  2. Sep 25, 2026Тысячи ИИ-агентов одновременно читают продакшен-базу. Что происходит с PostgreSQL? Google…
  3. Sep 24, 2026Softmax простыми словами: что значат 66,5% в ответе нейросети? Softmax простыми словами: C…
  4. Sep 24, 2026🔥Один слой данных вместо цепочки копий между системами В традиционной аналитической инфра…
  5. Sep 23, 2026⚡️ SQL-задача с опасным подвохом Какой баланс получит аккаунт после выполнения запроса в P…
  6. Sep 22, 2026🌟 Samsone: открытые аудиоязыковые модели для смартфонов Samsung опубликовали Samsone - се…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →