Как посчитать количество строк в SQL
Число строк в таблице:
SELECT COUNT(*) FROM people;Запрос одинаков в SQLite, MySQL, PostgreSQL и других СУБД. Ниже примеры на такой таблице:
CREATE TABLE people (
id INTEGER PRIMARY KEY,
name TEXT,
phone TEXT,
city TEXT
);
INSERT INTO people (name, phone, city) VALUES
('Анна', '+375291112233', 'Минск'),
('Борис', NULL, 'Гомель'),
('Вера', '+375447778899', 'Минск'),
('Глеб', NULL, 'Минск');Три вида COUNT
SELECT COUNT(*) AS all_rows,
COUNT(phone) AS with_phone,
COUNT(DISTINCT city) AS cities
FROM people;| all_rows | with_phone | cities |
|---|---|---|
| 4 | 2 | 2 |
COUNT(*)— все строки, какими бы они ни были;COUNT(phone)— строки, гдеphoneнеNULL(у Бориса и Глеба телефона нет);COUNT(DISTINCT city)— сколько разных значений: Минск и Гомель.
COUNT(1) работает так же, как COUNT(*), и не быстрее его.
По условию и по группам
Строки, подходящие под условие, — WHERE:
SELECT COUNT(*) FROM people WHERE city = 'Минск';Ответ — 3. Число строк в каждой группе — GROUP BY:
SELECT city, COUNT(*) AS total
FROM people
GROUP BY city
ORDER BY total DESC;| city | total |
|---|---|
| Минск | 3 |
| Гомель | 1 |
Отобрать группы по числу строк (например, города, где больше двух человек) — HAVING COUNT(*) > 2, см. справку Чем WHERE отличается от HAVING.
Несколько условий одним запросом
Всего людей и сколько из них без телефона — без двух отдельных запросов:
SELECT COUNT(*) AS total,
SUM(CASE WHEN phone IS NULL THEN 1 ELSE 0 END) AS no_phone
FROM people;| total | no_phone |
|---|---|
| 4 | 2 |
CASE даёт 1 для подходящих строк и 0 для остальных, SUM складывает единицы. Такая запись работает везде. В PostgreSQL и SQLite 3.30 и новее есть и короче: COUNT(*) FILTER (WHERE phone IS NULL).
Число строк сложного запроса
Посчитать строки результата с DISTINCT, JOIN или GROUP BY проще всего, обернув его в подзапрос:
SELECT COUNT(*) FROM (
SELECT DISTINCT name, city FROM people
) AS t;Подводные камни
- Пустой результат.
SELECT COUNT(*) … WHERE city = 'Витебск'вернёт строку с 0. А тот же запрос сGROUP BY cityне вернёт ни одной строки: групп нет. - COUNT и LEFT JOIN. При подсчёте связанных строк считайте столбец правой таблицы:
COUNT(o.id), а неCOUNT(*)— иначе у строк без пары получится 1 вместо 0. Подробно — в справке Чем LEFT JOIN отличается от INNER JOIN. - Большие таблицы. В PostgreSQL и MySQL (InnoDB)
COUNT(*)по таблице в миллионы строк заметно долгий: СУБД честно проходит строки. Если хватит примерного числа, в PostgreSQL его хранит служебная таблицаpg_class(столбецreltuples), в MySQL —SHOW TABLE STATUS(столбецRows). - Число строк после изменения. Сколько строк задела последняя команда
UPDATEилиDELETE, в SQLite показываетSELECT changes();, в MySQL —SELECT ROW_COUNT();.