У меня две таблицы
Customer (idCustomer, ecc.. ecc..) Comment (idCustomer, idComment, ecc.. ecc..)
очевидно, что две таблицы объединены, например
SELECT * FROM Comment AS co JOIN Customer AS cu ON cu.idCustomer = co.idCustomer
При этом я выбираю все комментарии из этой таблицы, связанной с Customer, но теперь я хочу ограничить количество комментариев на 2 max Comment для клиента.
Первое, что я вижу, это использовать GROUP BY cu.idCustomer
но он ограничивает только 1 Комментарий для Клиента, но я хочу 2 комментария для Клиента.
Как я могу это достичь?
Один из вариантов в MySQL – это серверные переменные. Например:
set @num := 0, @customer := -1; select * from ( select idCustomer , commentText , @num := if(@customer = idCustomer, @num + 1, 1) as row_number , @customer := idCustomer from Comments order by idCustomer, PostDate desc ) as co join Customer cu on co.idCustomer = cu.idCustomer where co.row_number <= 2
Эта версия не требует операции SET:
select * from (select idCustomer , commentText , @num := if(@customer = idCustomer, @num + 1, 1) as row_number , @customer = idCustomer from Comments JOIN(SELECT @num := 0, @customer := 1) r order by idCustomer, PostDate desc) as co join Customer cu on co.idCustomer = cu.idCustomer where co.row_number <= 2
SELECT * FROM Comments AS cm1 LEFT JOIN Comments AS cm2 ON cm1.idCustomer = cm2.idCustomer LEFT JOIN Customer AS cu ON cm1.idCustomer = cu.idCustomer WHERE cm1.idComment != cm2.idComment GROUP BY cm1.idCustomer
Однако, если вы собираетесь изменить количество комментариев, лучше использовать решение Andomar .
Нет необходимости использовать курсор, который очень медленный. См. Мой ответ на сложный SQL-запрос о подключении и ограничении . DENSE_RANK сделает трюк без всяких тонкостей курсора.
Если вы используете язык сценариев, такой как PHP для обработки результатов, вы можете ограничить количество результатов, отображаемых для каждого клиента после выполнения запроса. Настройте массив для хранения всех результатов, настройте еще один массив, чтобы удержать количество результатов на каждого клиента и прекратить добавлять результаты запроса к набору результатов после того, как счет превысит ваш предел следующим образом:
$RESULTS = array(); $COUNTS = array(); $limit = 2; $query = "SELECT customer_id, customer_name, customer_comment FROM customers ORDER BY RAND()"; $request = mysql_query($query); while ($ROW = mysql_fetch_assoc($request)) { $c = $ROW['customer_id']; $n = $COUNTS[$c]; if ($n<$limit) { $RESULTS[] = $ROW; $COUNTS[$c]++; } }
Это гарантирует, что только два комментария на одного клиента будут показаны вытащенными случайным образом или, как вы хотите, остальные будут выброшены. Конечно, вы тянете ВСЕ результаты, но это (возможно) быстрее, чем сложное соединение.