В следующем SQL-запросе на PostgreSQL: SELECT u.id, COUNT(o.*) FROM users u LEFT JOIN orders o ON o.user_id = u.id WHERE o.status = 'completed' GROUP BY u.id; объясните логическую ошибку и предложите исправление
Проблема: условие в `WHERE o.status = 'completed'` отбрасывает строки с `o IS NULL`, поэтому LEFT JOIN фактически превращается в INNER JOIN — вы получите только пользователей у которых есть хотя бы один выполненный заказ, а пользователей с нулём выполненных заказов не увидите. Исправления (варианты): 1) Перенести фильтр в ON, тогда LEFT JOIN сохранит пользователей без заказов: ``` SELECT u.id, COUNT(o.id) FROM users u LEFT JOIN orders o ON o.user_id = u.id AND o.status = 'completed' GROUP BY u.id; ``` 2) Оставить условие в JOIN и/или агрегировать с FILTER: ``` SELECT u.id, COUNT(o.id) FILTER (WHERE o.status = 'completed') AS completed_count FROM users u LEFT JOIN orders o ON o.user_id = u.id GROUP BY u.id; ``` Примечания: - Лучше считать по явному ключу `o.id`, а не по `o.*`. - В первом варианте пользователи без выполненных заказов получат значение ‘0‘`0`‘0‘ в счётчике.
Исправления (варианты):
1) Перенести фильтр в ON, тогда LEFT JOIN сохранит пользователей без заказов:
```
SELECT u.id, COUNT(o.id)
FROM users u
LEFT JOIN orders o
ON o.user_id = u.id AND o.status = 'completed'
GROUP BY u.id;
```
2) Оставить условие в JOIN и/или агрегировать с FILTER:
```
SELECT u.id,
COUNT(o.id) FILTER (WHERE o.status = 'completed') AS completed_count
FROM users u
LEFT JOIN orders o
ON o.user_id = u.id
GROUP BY u.id;
```
Примечания:
- Лучше считать по явному ключу `o.id`, а не по `o.*`.
- В первом варианте пользователи без выполненных заказов получат значение ‘0‘`0`‘0‘ в счётчике.