#php #mysql
#php #mysql
Вопрос:
У меня есть некоторые данные об агентах, голосующих за разные варианты в разное время:
------------ ------------- ------ ----- --------- ----------------
| Field | Type | Null | Key | Default | Extra |
------------ ------------- ------ ----- --------- ----------------
| ID | int(10) | NO | PRI | NULL | auto_increment |
| option | varchar(50) | NO | | NULL | |
| agent | varchar(50) | NO | | NULL | |
| date | datetime | NO | | NULL | |
------------ ------------- ------ ----- --------- ----------------
Теперь я хотел бы вывести все строки, в которых по крайней мере a агентов проголосовали по крайней мере в t дат за один из не более o вариантов.
Итак, предположим, например, a = 2, t = 3, o = 1. Затем я хочу вывести только те строки, сумма которых равна (count)>= 3 * 2 и в которых по крайней мере для 3 разных дат являются голосования за один из не более 1 варианта из 2 разных агентов. Например.:
Команда выбора, которую я ищу, должна выводиться из:
-------- ------- ------
| option | agent | date |
-------- ------- ------
| opt1 | a | 1 |
| opt1 | a | 2 |
| opt1 | a | 3 |
| opt2 | b | 1 |
| opt2 | b | 2 |
| opt2 | b | 3 |
| opt1 | c | 1 |
| opt1 | c | 2 |
| opt1 | c | 3 |
-------- ------- ------
Только строки агента a и c:
-------- ------- ------
| opt1 | a | 1 |
| opt1 | a | 2 |
| opt1 | a | 3 |
| opt2 | b | 1 |
| opt1 | c | 1 |
| opt1 | c | 2 |
| opt1 | c | 3 |
-------- ------- ------
Есть ли способ сделать это или мне нужно выполнить набор комбинаций через скрипт (PHP)? Большое спасибо, Кристиан
Комментарии:
1. Я несколько смущен вашими требованиями. Можете ли вы добавить еще несколько этапов к своему описанию. Я не понимаю, почему агент b находится в конечных результатах один раз, когда все 3 их записи кажутся одинаковыми, или это только опечатка?
2. Для меня это путаница: «проголосовал по крайней мере в t дат за один из не более o вариантов». является ли 0 опечаткой?
3. Спасибо за ваши комментарии! @Kickstart: мне очень жаль — строка с агентом b в выходных данных неверна. ad Len_D: «o» обозначает количество опций. На самом деле, я мог бы упростить логику запроса, в котором я нуждаюсь, следующим образом: показать все строки так, чтобы для строк a * t были агенты A1, …, Aa , даты T1, …, Tt и опции O1, …, Oo , такие, что каждый из агентов выбирает для каждой даты по одному выходуиз опций O1, …, Oo . …
4. ad Kickstart и @Len_D: в PHP-скрипте я бы пробежался по всем подмножествам набора дат с ровно t элементами и вывел бы все эти подмножества, где пересечение всех агентов, выбирающих на некоторую дату в подмножестве, имеет по крайней мере элементы и где объединение опций, выбранных с помощьюточно агенты имеют не более o элементов. Но проблема в том, что эта процедура занимает довольно много времени и с более чем 2500 датами невозможно выполнить.
Ответ №1:
Думаю, вам понадобится пара вложенных запросов. Один, чтобы получить все параметры / агенты с как минимум таким количеством дат, сколько требуется, а затем использовать это в качестве источника для другого запроса, чтобы найти количество опций с как минимум требуемым количеством агентов. Затем объедините результаты этого запроса с вашей таблицей, чтобы получить подробную информацию об этих параметрах.
SELECT sometable.`option`, sometable.agent, sometable.date
FROM
(
SELECT `option`, COUNT(DISTINCT agent) as distinct_agents
FROM
(
SELECT `option`, agent, COUNT(DISTINCT date) AS distinct_dates
FROM sometable
GROUP BY `option`, agent
HAVING distinct_dates >= 3
) sub0
GROUP BY `option`
HAVING distinct_agents >=2
) sub1
INNER JOIN sometable
ON sub1.`option` = sometable.`option`
SQL-скрипка для него:-