SQL — Урок 8. Группировка записей и функция COUNT()
Давайте вспомним, какие сообщения и в каких темах у нас имеются. Для этого можно воспользоваться привычным запросом:
А что, если нам надо лишь узнать сколько сообщений на форуме имеется. Для этого можно воспользоваться встроенной функцией COUNT(). Эта функция подсчитывает число строк. Причем, если в качестве аргумента этой функции выступает *, то подсчитываются все строки таблицы. А если в качестве аргумента указывается имя столбца, то подсчитываются только те строки, которые имеют значение в указанном столбце.
В нашем примере оба аргумента дадут одинаковый результат, т.к. все столбцы таблицы имеют тип NOT NULL. Давайте напишем запрос, используя в качестве аргумента столбец id_topic:
SELECT COUNT(id_topic) FROM posts;
Итак, в наших темах имеется 4 сообщения. Но что, если мы хотим узнать сколько сообщений имеется в каждой теме. Для этого нам понадобится сгруппировать наши сообщения по темам и вычислить для каждой группы количество сообщений. Для группировки в SQL используется оператор GROUP BY. Наш запрос теперь будет выглядеть так:
SELECT id_topic, COUNT(id_topic) FROM posts GROUP BY id_topic;
Оператор GROUP BY указывает СУБД сгруппировать данные по столбцу id_topic (т.е. каждая тема — отдельная группа) и для каждой группы подсчитать количество строк:
Ну вот, в теме с у нас 3 сообщения, а с — одно. Кстати, если бы в поле id_topic были возможны отсутствия значений, то такие строки были бы объединены в отдельную группу со значением NULL.
Предположим, что нас интересуют только те группы, в которых больше двух сообщений. В обычном запросе мы указали бы условие с помощью оператора WHERE, но этот оператор умеет работать только со строками, а для групп те же функции выполняет оператор HAVING:
SELECT id_topic, COUNT(id_topic) FROM posts GROUP BY id_topic HAVING COUNT(id_topic) > 2;
В результате имеем:
В уроке 4 мы рассматривали, какие условия можно задавать оператором WHERE, те же условия можно задавать и оператором HAVING, только надо запомнить, что WHERE фильтрует строки, а HAVING — группы.
Итак, сегодня мы узнали, как создавать группы и как подсчитать количество строк в таблице и в группах. Вообще вместе с оператором GROUP BY можно использовать и другие встроенные функции, но их мы будем изучать позже.
Научись программировать на Python прямо сейчас!
- Научись программировать на Python прямо сейчас
- Бесплатный курс
Если этот сайт оказался вам полезен, пожалуйста, посмотрите другие наши статьи и разделы.
Как в sql посчитать количество повторяющихся значений
Можно попробовать использовать функцию COUNT() в сочетании с оператором GROUP BY .
Предположим, у нас есть таблица «orders» с колонками «customer_name» и «order_date» , и мы хотим посчитать, сколько заказов было сделано каждым клиентом. Мы можем написать следующий SQL-запрос:
Этот запрос выберет все уникальные значения из колонки «customer_name» в таблице «orders» и подсчитает количество строк, связанных с каждым уникальным значением. Результатом запроса будет таблица со столбцами «customer_name» и «order_count» , в которой каждая строка будет показывать клиента и количество его заказов.
Форум пользователей MySQL
Подскажите селект для выборки идентичных (повторяющихся либо похожих) значений в определенном столбике таблицы.
Для примера:
таблица — «table»
столбик — «column»
#2 20.12.2008 23:28:29
vasya Архат Откуда: Орел Зарегистрирован: 07.03.2007 Сообщений: 5817
Re: Запрос для выборки одинаковых значений
Не понятно, что значит похожих. Для выборки повторяющихся значений без повторов:
SELECT ` column ` FROM ` table ` GROUP BY ` column ` HAVING count ( * ) > 1 ;
Для выборки всех повторяющихся значений (с повторами):
SELECT ` column ` FROM ` table ` WHERE ` column ` LIKE (
SELECT ` column ` FROM ` table ` GROUP BY ` column ` HAVING count ( * ) > 1 ) ;
#3 20.12.2008 23:50:07
Fader Завсегдатай Зарегистрирован: 07.05.2008 Сообщений: 54
Re: Запрос для выборки одинаковых значений
Пытаюсь выполнить в phpmyadmin тот селект что «Для выборки всех повторяющихся значений (с повторами)» — получаю ошибку:
#1242 — Subquery returns more than 1 row
Под похожими подразумеваю фразы имеющие одинаковое начало или окончание или «корень»:
Firefox 3.0.5 Final
Firefox 3.0.5 Final Russian
Браузер Firefox 3.0.5
#4 21.12.2008 01:23:18
vasya Архат Откуда: Орел Зарегистрирован: 07.03.2007 Сообщений: 5817
Re: Запрос для выборки одинаковых значений
Замените LIKE на IN
SELECT ` COLUMN ` FROM ` table ` WHERE ` COLUMN ` IN ( SELECT ` COLUMN ` FROM ` table ` GROUP BY ` COLUMN ` HAVING count ( * ) > 1 ) ;
#5 20.07.2010 18:49:43
Fader Завсегдатай Зарегистрирован: 07.05.2008 Сообщений: 54
Re: Запрос для выборки одинаковых значений
Спасибо за запрос. В свое время он мне здорово помог.
Но сейчас проблема возникла снова:
За это время база существенно подросла и запрос выполняется неимоверно долго. (в таблице около 25к строк). Ждал около часа — надоело.
Пытался оптимизировать производительность mysql сервера, надеялся что запрос будет выполняться быстрей — ничего не вышло.
Подскажите как решить проблему?
#6 20.07.2010 19:30:21
paulus Администратор Зарегистрирован: 22.01.2007 Сообщений: 6756
Re: Запрос для выборки одинаковых значений
Хм. А вообще подзапрос нужен?
SELECT `colname` FROM `tablename` GROUP BY 1 HAVING COUNT(*) > 1;
Нужен ключик по (`colname`).
#7 20.07.2010 21:24:44
Fader Завсегдатай Зарегистрирован: 07.05.2008 Сообщений: 54
Re: Запрос для выборки одинаковых значений
Хм. работает! Спасибо!
Только что вы имели ввиду: «Нужен ключик по (`colname`)»?
#8 21.07.2010 13:38:41
paulus Администратор Зарегистрирован: 22.01.2007 Сообщений: 6756
Re: Запрос для выборки одинаковых значений
Слово «индекс» Вам больше нравится?
#9 28.07.2010 02:11:35
Fader Завсегдатай Зарегистрирован: 07.05.2008 Сообщений: 54
Re: Запрос для выборки одинаковых значений
возникла необходимость усложнить запрос.
К данному селекту нужно добавить условие:
среди повторяющихся значений выбрать нужно то, где дата в столбце ‘date’ (type=datetime) более поздняя
#10 28.07.2010 11:17:02
paulus Администратор Зарегистрирован: 22.01.2007 Сообщений: 6756
Re: Запрос для выборки одинаковых значений
SELECT `colname`, MAX(`date`) FROM `tablename` GROUP BY 1 HAVING COUNT(*) > 1;
#11 10.02.2011 18:52:13
nexus Завсегдатай Зарегистрирован: 26.11.2010 Сообщений: 35
Re: Запрос для выборки одинаковых значений
А как изменить запрос, если мне надо выбрать только те записи,у которых значение столбца COLUM повторяется у всех элементов с индексом (1-10).
Ну например, имеется таблица
CREATE TABLE IF NOT EXISTS `site_autos_params` (
`id` int ( 11 ) NOT NULL auto_increment ,
`auto_id` int ( 11 ) NOT NULL ,
`param_id` int ( 11 ) NOT NULL ,
`variant_id` int ( 11 ) NOT NULL ,
`value` varchar ( 255 ) NOT NULL ,
PRIMARY KEY ( `id` ) ,
KEY `auto_id` ( `auto_id` ) ,
KEY `param_id` ( `param_id` )
) ENGINE = MyISAM DEFAULT CHARSET =utf8 AUTO_INCREMENT = 14 ;
INSERT INTO `site_autos_params` ( `id`, `auto_id`, `param_id`, `variant_id`, `value` ) VALUES
( 1 , 6 , 25 , 0 , ‘Белый’ ) ,
( 2 , 5 , 25 , 0 , ‘Бронзовый’ ) ,
( 3 , 4 , 25 , 0 , ‘Белый’ ) ,
( 4 , 3 , 25 , 0 , ‘Белый’ ) ,
( 5 , 1 , 25 , 0 , ‘Белый’ ) ,
( 6 , 6 , 21 , 0 , ‘Бензин’ ) ,
( 7 , 5 , 21 , 0 , ‘Бензин/Газ’ ) ,
( 8 , 3 , 21 , 0 , ‘Бензин’ ) ,
( 9 , 7 , 21 , 0 , ‘Газ’ ) ,
( 10 , 7 , 25 , 0 , ‘Голубой’ ) ;
Мне нужно выбрать те записи у которых auto_id IN (‘4’, ‘5’, ‘6’, ‘7’) и которые имеют одинаковый param_id.
Т.е. нужно выбрать только те параметры, которые встречаются у всех автомобилей!
Пробывал делать так:
SELECT `auto_id`, `param_id`, `value`
FROM ( `site_autos_params` )
WHERE `param_id` IN ( SELECT `param_id` FROM site_autos_params GROUP BY `param_id` HAVING count ( * ) > 1 )
AND `auto_id` IN ( ‘4’ , ‘5’ , ‘6’ , ‘7’ )
Но этот запрос не правильно отрабатывает. Мне именно надо получить те параметры, которые есть у всех авто!
Количество одинаковых строк
Добрый день, быть может подскажет кто.
Есть некоторая таблица, порядка 500000 строк, три столбца.
Встал вопрос подсчета количества одинаковых значений вида
Если первый и второй столбец одной строки равны другому, то считать их одинаковыми и вывести количество таких строк.
Но, соответственно, пары могут быть разные, например
1 2 4
1 3 5
1 2 1
1 2 9
1 3 3
И результат 1 2 — 3 штуки, 1 3 — 2 штуки.
Представляю, как это реализовать на Яве, через массивы и циклы проблем не возникнет, например, но как написать такой sql-запрос придумать не получается.. Пытался джойнить таблицу саму к себе — безрезультатно.
Заранее благодарен за помощь
Была еще мысль выгрузки в Excel с дальнейшим подсчетом, но там возникли проблемы с тем, что нельзя (или я не знаю как) задать «общее» условие, т.е. использовать не конкретную ячейку, а n-ую.
94731 / 64177 / 26122