Как получить счет двух разных полей с группой в MySQL? Mysql group by несколько полей


Mysql - Оптимизация SELECT GROUP BY по нескольким полям | PHPClub

Всем привет. Тружусь над разработкой системы по управлению медийной рекламы на сайте. Одна из основных частей проекта - сбор статистики показов и кликов, при этом надо хранить страну и тип девайса, с которого совершен запрос.

Вот таблица статистики:

Код:

create table statistics ( visit_date int default '0' not null, sait_id int default '0' not null, block_id int default '0' not null, advertisement_id int default '0' not null, teaser_group_id int default '0' not null, teaser_id int default '0' not null, link_id int default '0' not null, device_type smallint(2) default '0' not null, advertisement_system varchar(255) default '' not null, country varchar(4) default '' not null, visit_guid bigint default '0' not null, id bigint not null auto_increment, primary key (visit_guid, visit_date, sait_id, block_id, advertisement_id, teaser_group_id, teaser_id, text_block_id, custom_widget_id, banner_id, link_id, device_type, country) ) ; create index statisticsId on statistics (id) ; comment on column statistics.device_type is 'Тип трафика, 1 - мобильный, 2 - десктоп' ; В нее за день набегает в среднем 1,5 миллиона записей, значит в месяц около 45 миллиона записей.

Теперь самое главное. Нужно просматривать статистику с группировкой по 2-м полям. Например такой запрос:

Код:

SELECT sait_id, count(id) AS counter, link_id FROM statistics WHERE statistics.visit_date = 1498694400 GROUP BY sait_id, link_id; вот его EXPLAIN:1. MYISAM[​IMG]2. INNODB[​IMG]

При 3-х миллионах записей MySQL падает, при 1-ом миллионе скорость выборки где-то 15-20 секунд.

Простановка индексов по 2-м полям не сильно помогла. Нужна ваша помощь для оптимизации самой таблицы statistics и запроса.

 

phpclub.ru

GROUP BY по двум полям (MySQL)

GANJAR В таблице есть поля email и email_rec. нужно сделать GROUP BY так, что бы в результат был количеством записей из данными типа:

email - email_rec email_rec - email

То есть по 2-м полям группировка. В результат должны попасть как входящие так и исходящие сообщения. На первый взгляд показалось все довольно просто, а сейчас уже более 5ти ч. И ни в какую…Дополнено (1). Есть 2 поля: получатель и отправитель. Нужно получить количество записей входящих и исходящих сообщений. То есть -значение первой записи получатель [email protected] а отправитель [email protected] -второй - получатель [email protected] а отправитель [email protected] В итоге они должны быть подсчитаны COUNT(*) AS 'count_msg' А как сам запрос группировки составить я без понятия…Дополнено (2). |277|21|21|0|0|[email protected]| | |etsets|1297930874|1|0| |[email protected]|1 |387|21|21|0|103241|[email protected]|Богдан| |qweqwe|1298387575|1|1| |[email protected]|1 |402|21|21|0|103241|[email protected]|Богдан| |tsetseet|1298455480|1|0| |[email protected]|1

В результате должно получится 2 и 1 Потому как 3 строка в поле получатель содержит другой email Групировка по 2м полям когда отправитель и получатель должны попасть в один результат.Дополнено (3). Psevdonim, так я первым делом и сделал сначала, но результат не тот который мне нужно. Мне нужно подсчитать как исходящие так и входящие сообщения. А группировка по 2м полям даст лишь подсчет либо входящих либо исходящих. Так как во входящих сообщениях email отправителя = email получателя, в исходящих соответственно наоборот. В этом и вся сложностьДополнено (4). Решение найдено. GROUP BY IF('email'="'.$mail_acc['email'].'", 'email_rec', 'email') Спасибо всем отписавшимся.

ИгоряN Если я правильно понял, то у тебя с тем что ты хочешь получится то количество записей которое есть в базе и никакой групировки не выйдет, тебе надо два запроса писать

Иван Говно Я ничего не понял.

upd. Каждому реальному письму соответсвует две записи в таблице? Все равно не понятно. Давай напримере. Список писем, что в таблице и что должно быть в результате.

Psevdonim SELECT count(*) AS 'count_msg', email, email_rec FROM GROUP BY email, email_rec ;

В чём проблемы-то?

mysqlru.com

Группировка записей MySQL: group by

Группировка и анализ записей таблиц базы данных представляют практический интерес во многих областях применения. Решение такого рода задач средствами MySQL позволяет выполнить большие объёмы рутинной работы быстро и эффективно.

mysql group by

Следует, однако, иметь в виду: «чистота», получаемого результата будет зависеть от множества факторов. Конструкция MySQL group by исполняется так, как записано программистом, но алгоритм её может зависеть от времени исполнения запроса и частоты выборки.

Синтаксис операции группировки в запросе

При составлении запроса на группировку имеет существенное значение что именно выбирается и как оно группируется. Исходная таблица содержит небольшое количество полей, каждое из которых имеет различное количество уникальных записей. Поля i_status и w_status эквивалентны: первое - код должности, второе - её наименование. Поле номера записи и времени создания записи не имеют особого значения.

Авторский пример - это не картинка

На таком наборе можно выполнить групповые операции, например определить максимальное и минимальное значение поля start_timestamp.

Авторский пример - это не картинка

Аналогично можно сформулировать групповой запрос и определить все должности и количество людей, занятых на них.

Авторский пример - это не картинка

Соотношение MySQL: group by & order by прослеживается на запросах (i) и (iv), запросы (ii) и (iii) эквивалентны. Но в любой конкретной ситуации следует продумать, как выполнять сортировку при выполнении операции группировки. В некоторых случаях это может составлять проблему.

mysql group by order by

Подсчёт количества группируемых записей - важный момент при группировке. данная операция, в основном используется именно для этих целей, хотя её использование для определения различных строк в таблице в некотором роде удобнее, в отличие от конструкции distinct.

Группировка по объему вхождения

Следует обратить внимание, что MySQL group by не всегда сработает против MySQL order by. Вопрос не столько в приоритетах конструкций, сколько в логике самого запроса.

Запрос может быть сформулирован как выражение. В самом простом случае выражение может состоять в подсчёте количества. То есть применение в MySQL group by, count(*) - в качестве выражения, по которому выполняется группировка.

Авторский пример - это не картинка

Здесь сортировка по возрастанию имеет значение та, которая указана в order by.

Язык MySQL не ограничивает программиста в конструировании выражений, указании полей, которые не участвуют в группировке, последовательности группируемых элементов. Но MySQL group by может не сработать так, как считает правильным программист.

Множественная группировка

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

Авторский пример - это не картинка

MySQL group by - очень удобная операция на повторяющихся данных, с её помощью легко можно получить нужную информацию, но если в запросе происходит группировка нескольких полей целесообразно рассмотреть иные варианты построения запроса.

Следует принимать во внимание, что конструкции group by и order by язык MySQL рассматривает как простую «арифметику» над записями. Для ответственных операций группировки предназначены варианты встроенных запросов, разумное применение ключей, объединение и пересечение таблиц.

mysql group by count

Группировка в контексте MySQL group by - это быстрое получение обобщённой информации, не следует нагружать запросы с этой конструкцией более глубоким смыслом. Это может привести к непредсказуемым результатам и серьёзным затратам времени.

fb.ru

mysql - Группа mysql group_concat по нескольким полям

Трудно понять, что именно вы после своего вопроса, но можете попробовать

SELECT club_name, GROUP_CONCAT(DISTINCT email SEPARATOR ', ' ) emails, GROUP_CONCAT(DISTINCT member_name SEPARATOR ', ' ) members ... FROM member GROUP BY club_name

Пример вывода:

| CLUB_NAME | EMAILS | MEMBERS | ------------------------------------------------------------------------ | Club1 | [email protected], [email protected], [email protected] | Jhon, Mark, Beth | | Club2 | [email protected], [email protected] | Helen, Thomas |

Вот демоверсия SQLFiddle

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

ОБНОВЛЕНИЕ: вы можете глубоко упаковать информацию, используя GROUP_CONCAT() используя разные разделители, если это то, что вы хотите

SELECT 'club' group_type, GROUP_CONCAT(details SEPARATOR '|') details FROM ( SELECT CONCAT(club_name, ';', GROUP_CONCAT(DISTINCT email)) details FROM member GROUP BY club_name ) a UNION ALL SELECT 'region' group_type, GROUP_CONCAT(details SEPARATOR '|') details FROM ( SELECT CONCAT(region, ';', GROUP_CONCAT(DISTINCT email)) details FROM member GROUP BY region ) a UNION ALL SELECT 'zone' group_type, GROUP_CONCAT(details SEPARATOR '|') details FROM ( SELECT CONCAT(zone, ';', GROUP_CONCAT(DISTINCT email)) details FROM member GROUP BY zone ) a

Пример вывода:

| GROUP_TYPE | DETAILS | ----------------------------------------------------------------------------------------------------------------------- | club | A;[email protected],[email protected]|B;[email protected]|C;[email protected]|D;[email protected] | | region | 1;[email protected],[email protected],[email protected],[email protected]|2;[email protected] | | zone | 1;[email protected],[email protected],[email protected],[email protected]|2;[email protected] |

Вот демоверсия SQLFiddle

Если вы используете php на стороне клиента, тогда вы можете достаточно легко развернуть колонку details в отдельные записи, используя explode() когда вы выполняете итерацию по набору результатов.

qaru.site

php - ВЫБРАТЬ все совпадающие два поля и группировать эти два поля с помощью mysql

Вероятно, вы получаете два ответа на чат, потому что у вас будет каждый человек в обеих позициях.

ChatID Sender Receiver 1 1 2 2 2 1 3 1 2 4 2 1 So, you'll have a record grouped by Sender / Receiver 1 2 and 2 1

Я думаю, что то, что вы ищете, - это разные люди в разговоре, где выше следует рассматривать "ОДИН ЧАТ", независимо от того, в каком положении они находятся. Чтобы исправить это, я бы сделал что-то вроде...

select PreQuery.*, m2.Message, m2.SenderID, m2.ReceiverID from ( SELECT if( m.senderID < m.receiverID, m.senderID, m.receiverID ) as Person1, if( m.senderID < m.receiverID, m.receiverID, m.senderID ) as Person2, max( m.ID ) as LastMessageIDPerChat, max( m.AddedDate ) as LastMessageDate FROM messages m WHERE m.Source = "1" AND "1" IN ( SenderID, ReceiverID ) GROUP BY Person1, Person2 ORDER BY m.AddedDate DESC LIMIT 10 ) PreQuery JOIN Messages m2 on PreQuery.LastMessageIDPerChat = m2.ID

Это гарантирует, что какой бы идентификатор ни был ниже, всегда будет находиться в первой позиции, и какой бы идентификатор человека был выше, всегда находится во второй позиции, чтобы предотвратить ложные дубликаты, как описано выше.

Также обратите внимание... GROUP BY обычно ожидает, что все негрупповые поля будут связаны с некоторой агрегацией, в противном случае он просто захватит первый экземпляр записи, найденной с квалификационным условием. Итак, если вы хотите включать в разговоры тех же людей в разные дни, вам нужно добавить "AddDate" в группу, чтобы он мог...

Person1 Person2 on 4/20 Person1 Person3 on 4/20 Person3 Person4 on 4/20 Person1 Person2 on 4/18 Person1 Person5 on 4/17 Person3 Person4 on 4/15

Чтобы получить статус того, кто отправил последний, мне пришлось обернуть запрос парных людей на беседу и получить последний идентификатор этого разговора. ТОГДА, возьмите это и снова присоединитесь к сообщениям на этом ID (если Идентификатор фактически является идентификатором первичного ключа таблицы сообщений, при необходимости отрегулируйте). Из соединения я могу получить последнее сообщение для разговора И, для которого идентификатор отправителя и идентификатор получателя были для этой транзакции (и любые другие данные, которые вы хотите получить из ссылки псевдонима "m2" ).

qaru.site

sql - Как получить счет двух разных полей с группой в MySQL?

Глядя на ваш SQL, я немного не уверен, что вы хотите.

Обе части извлекают eTG.evrak_tipi_grup_adi и eT.evrak_tipi, но одна группа одна, а вторая группа - другая. Если значения, отличные от негруппового поля, различаются для сгруппированного поля, тогда возвращаемое значение относится к неуточненной строке, поэтому, вероятно, будет бессмысленным.

Если значения не меняются (т.е. Любая запись на evrak_tipleri имеет только одну запись на evrak_tipi_gruplari - предположим тип документа и тип документа), то ваши текущие запросы могут быть записаны как:

SELECT eTG.evrak_tipi_grup_adi, eT.evrak_tipi, COUNT(eTG.evrak_tipi_grup_adi) AS toplamGrup FROM evraklar evr LEFT JOIN kullanicilar kull ON evr.evrak_kaydeden_ybs_kullanici_id=kull.id LEFT JOIN evrak_tipleri eT ON evr.evrak_tipi=eT.id LEFT JOIN evrak_tipi_gruplari eTG ON evr.evrak_tipi_grubu=eTG.id GROUP BY eTG.evrak_tipi_grup_adi, eT.evrak_tipi SELECT eTG.evrak_tipi_grup_adi, eT.evrak_tipi, COUNT(eT.evrak_tipi) AS toplamTiptekiler FROM evraklar evr LEFT JOIN kullanicilar kull ON evr.evrak_kaydeden_ybs_kullanici_id=kull.id LEFT JOIN evrak_tipleri eT ON evr.evrak_tipi=eT.id LEFT JOIN evrak_tipi_gruplari eTG ON evr.evrak_tipi_grubu=eTG.id GROUP BY eTG.evrak_tipi_grup_adi, eT.evrak_tipi

поэтому можно просто объединить с: -

SELECT eTG.evrak_tipi_grup_adi, eT.evrak_tipi, COUNT(eTG.evrak_tipi_grup_adi) AS toplamGrup, COUNT(eT.evrak_tipi) AS toplamTiptekiler FROM evraklar evr LEFT JOIN kullanicilar kull ON evr.evrak_kaydeden_ybs_kullanici_id=kull.id LEFT JOIN evrak_tipleri eT ON evr.evrak_tipi=eT.id LEFT JOIN evrak_tipi_gruplari eTG ON evr.evrak_tipi_grubu=eTG.id GROUP BY eTG.evrak_tipi_grup_adi, eT.evrak_tipi

Счет просто вернет количество ненулевых значений в этих полях. Я подозреваю, что вы, возможно, захотите использовать COUNT (DISTINCT....).

Однако это очень зависит от того, что вы хотите рассчитать и как таблицы относятся друг к другу (т.е. От одного до многих отношений и т.д.),

РЕДАКТИРОВАТЬ

Игнорирование пользователей сейчас, но я думаю, что это то, что вы хотите (используя имена таблиц и столбцов из скрипта sql): -

SELECT doc_types.id, doc_types.doc_type_name, Sub1.doc_type_group_name, COUNT(documents.id) AS DocsForDocType, Sub1.DocsForDocTypeGroup FROM doc_types LEFT OUTER JOIN documents ON doc_types.id = documents.doc_type_id LEFT OUTER JOIN ( SELECT doc_type_groups.id, doc_type_groups.doc_type_group_name, COUNT(documents.id) AS DocsForDocTypeGroup FROM doc_type_groups INNER JOIN documents ON doc_type_groups.id = documents.doc_type_group_id GROUP BY doc_type_groups.id, doc_type_group_name ) Sub1 ON doc_types.doc_type_group_id = Sub1.id GROUP BY doc_types.id, doc_types.doc_type_name, Sub1.doc_type_group_name, Sub1.DocsForDocTypeGroup;

Это получение типов документов и количества документов для этого типа, а также получение группы документов для типа документа и количества документов в этой группе.

qaru.site

Команда GROUP BY - группировка при выборке из базы данных

Команда GROUP BY позволяет группировать результаты при выборке из базы данных.

К сгруппированным результатам можно применять любые функции (смотрите примеры).

См. также команду HAVING, которая позволяет накладывать условие на группы, созданные с помощью GROUP BY.

Синтаксис

SELECT * FROM имя_таблицы WHERE условие GROUP BY поле_для_группировки

Примеры

Все примеры будут по этой таблице workers, если не сказано иное:

id айди name имя age возраст salary зарплата
1 Дима 23 100
2 Петя 23 200
3 Вася 23 300
4 Коля 24 1000
5 Иван 24 2000
6 Кирилл 25 1000

Пример

В данном примере записи группируются по возрасту (будет 3 группы - 23 года, 24 года и 25 лет). Затем для каждой группы применяется функция SUM, которая суммирует зарплаты внутри данной группы.

В результате для каждой из групп (23 года, 24 года и 25 лет) будет подсчитана суммарная зарплата внутри этой группы:

SELECT age, SUM(salary) as sum FROM workers GROUP BY age

SQL запрос выберет следующие строки:

age возраст sum сумма
23 600
24 3000
25 1000

Пример

В данном примере мы используем дополнительное условие WHERE, чтобы взять не все записи из таблицы:

SELECT age, SUM(salary) as sum FROM workers WHERE id>=2 GROUP BY age

SQL запрос выберет следующие строки:

age возраст sum сумма
23 500
24 3000
25 1000

Пример

В данном примере записи группируются по возрасту (будет 3 группы - 23 года, 24 года и 25 лет). Затем для каждой группы применяется функция MAX, которая находит максимальную зарплату внутри данной группы:

SELECT age, MAX(salary) as max FROM workers GROUP BY age

SQL запрос выберет следующие строки:

age возраст max максимальная зарплата
23 300
24 2000
25 1000

Пример

А теперь с помощью функции MIN найдется минимальная зарплата внутри данной группы:

SELECT age, MIN(salary) as min FROM workers GROUP BY age

SQL запрос выберет следующие строки:

age возраст min минимальная зарплата
23 100
24 1000
25 1000

Пример

А теперь с помощью функции COUNT найдется количество записей в группе:

SELECT age, COUNT(*) as count FROM workers GROUP BY age

SQL запрос выберет следующие строки:

age возраст count количество
23 3
24 2
25 1

code.mu