Сегодня поступил запрос на вывод повторяющихся строк в таблице. В старой версии портала, который мы используем для заявок, из-за отсутствия проверки была возможность несколько раз оценивать одну заявку. Это давало возможность для манипуляции статистикой. Подобное недопустимо, так как прямо противоречит критериям работы системы оценок.
На старом сервере установлен PHP5.6, поэтому нет возможности установить PhpMyAdmin. На самом деле установить его можно и не то чтобы это проблема, просто он там не особо нужен.
В целом, визуальные инструменты для работы с базами данных очень развращают. Начинаешь забывать как построить запрос на чистом SQL.
В результате решил освежить свои знания про SQL-запросы, а заодно немного оживить блог.
Итак, дана таблица SomeTable, содержащая некое поле SomeField. Нужно выбрать все строки, содержащие повторяющиеся значения поля SomeField и их количество. Т.е. выбрать строки, в которых поле записано более одного раза и посчитать сколько раз оно записано:
1 2 3 4 |
SELECT SomeFild, count(SomeFild) FROM SomeTable GROUP BY SomeFild HAVING count(SomeFild)>1; |
Результатом будет выведено поле по которому ищем и количество упоминаний.
У меня оценки состояли из семи полей, а таблица имела связь с таблицей head_table
, id для строк которой, попадали в колонку head
.
1 2 3 4 5 6 7 |
mysql> select * from tickets_balls where `head`=20474; # +-------+-------+------------+----------+----------+------------+------+ | id | head | date | ballTime | ballFull | ballClient | mean | +-------+-------+------------+----------+----------+------------+------+ | 17330 | 20474 | 1597919299 | 5 | 5 | 5 | 5.00 | +-------+-------+------------+----------+----------+------------+------+ |
Выполнив поиск по таблице, я получил длинный список повторяющихся оценок:
1 2 3 4 5 6 7 8 9 10 11 12 |
SELECT head, count(head) from tickets_balls GROUP BY head HAVING count(head)>1; # +-------+-------------+ | head | count(head) | +-------+-------------+ | 48 | 2 | | 121 | 6 | | 20442 | 2 | | 20464 | 3 | | 20468 | 2 | +-------+-------------+ 202 rows in set (0.01 sec) |
*В реальности список был намного длиннее.
Как видим, функция count()
прекрасно работает в SQL-запросах, где необходимо подсчитать количество вхождений.
Считать и выводить можно сразу по нескольким полям, для этого достаточно указать нужные поля через запятую. Указанные поля так же попадут на вывод, что удобно, если вам нужно получить идентификаторы полей с дублями.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
mysql> SELECT id, head, count(head) from tickets_balls GROUP BY head HAVING count(head)>1; # +-------+-------+-------------+ | id | head | count(head) | +-------+-------+-------------+ | 17256 | 20383 | 2 | | 17354 | 20384 | 7 | | 17240 | 20401 | 2 | | 17266 | 20421 | 4 | | 17579 | 20424 | 2 | | 17271 | 20431 | 2 | | 17286 | 20434 | 2 | | 17302 | 20442 | 2 | | 17339 | 20464 | 3 | | 17314 | 20468 | 2 | +-------+-------+-------------+ 202 rows in set (0.01 sec) |
Удалять дубликаты вручную довольно муторное занятие, особенно если заявок с повторяющимися оценками много. Пришлось немного напрячься составляя SQL-запрос.
Вывод: сегодня мы вернулись к азам SQL. Возможно, кому-то эта статья покажется простой, но работая с SQL через «призмы» языков программирования, забываешь, насколько сам SQL крут и сложен в своей простоте.