@viktorross

Как сгруппировать по убыванию?

Как запросе сгруппировать записи по убыванию? Чтобы вот этот подзапрос возвращал самую последнюю запись, весь запрос брал не первые, а самые последние записи
(select `class_messages`.`chat_message` order by `class_messages`.`id` desc limit 1) as last_message

Но группировка вот здесь судя по всему происходит таким образом, что остаются только первые результаты, т.е по возрастанию
group by `class_messages_chat`.chat_id desc order by class_messages.id desc;


SELECT `class_messages_chat`.`to_user_id`, 
       `class_messages_chat`.`from_user_id`, 
       `class_users`.`id`, 
       `class_users`.`user_status`, 
       `class_users`.`online`, 
       `class_messages_chat`.`chat_id`, 
       `class_messages_chat`.`ad_id`, 
       `class_ads`.user_id, 
       `class_ads`.title, 
       ( select `class_messages`.`chat_message` order by `class_messages`.`id` desc limit 1) as last_message 
FROM `class_messages_chat` 
inner join `class_ads` on `class_messages_chat`.ad_id = `class_ads`.id 
INNER JOIN `class_users` ON `class_users`.`id`=`class_ads`.`user_id` 
inner join `class_messages` on `class_messages_chat`.`chat_id` = `class_messages`.`chat_id` 
WHERE (`class_messages_chat`.`to_user_id` = 133337 or `class_messages_chat`.`from_user_id` = 133337) 
  and class_messages_chat.chat_id is not null 
group by `class_messages_chat`.chat_id desc 
order by class_messages.id desc;
  • Вопрос задан
  • 108 просмотров
Пригласить эксперта
Ответы на вопрос 1
@alexalexes
Если у вас MySQL 8+ версия, то список чатов получается тривиально - используя оконную функцию:
SELECT A.*
from (
SELECT class_messages.id as class_messages_id,
      `class_messages_chat`.`to_user_id`,
       `class_messages_chat`.`from_user_id`,
       `class_users`.`id`,
       `class_users`.`user_status`,
       `class_users`.`online`,
       `class_messages_chat`.`chat_id`,
       `class_messages_chat`.`ad_id`,
       `class_ads`.user_id,
       `class_ads`.title,
       row_number() over (partition by `class_messages_chat`.`chat_id` order by class_messages.id desc) rn -- этой функцией нумеруем в пределах чата сообщения
    FROM `class_messages_chat`
    inner join `class_ads` on `class_messages_chat`.ad_id = `class_ads`.id
    INNER JOIN `class_users` ON `class_users`.`id`=`class_ads`.`user_id`
    inner join `class_messages` on `class_messages_chat`.`chat_id` = `class_messages`.`chat_id`
WHERE (   `class_messages_chat`.`to_user_id` = 133337
       or `class_messages_chat`.`from_user_id` = 133337)
and class_messages_chat.chat_id is not null
) A
where A.Rn = 1 -- оставляем, все что с первым номером счетчика
order by A.class_messages_id desc

В mySQL 5.7
SELECT A.*
from (
SELECT
      `class_messages_chat`.`to_user_id`,
       `class_messages_chat`.`from_user_id`,
       `class_users`.`id`,
       `class_users`.`user_status`,
       `class_users`.`online`,
       `class_messages_chat`.`chat_id`,
       `class_messages_chat`.`ad_id`,
       `class_ads`.user_id,
       `class_ads`.title,
  IF(@prev <>  `class_messages_chat`.`chat_id`, @rn:=1,@rn), @prev:= `class_messages_chat`.`chat_id`, @rn:=@rn+1 AS rn -- этой функцией нумеруем в пределах чата сообщения
    FROM `class_messages_chat`
    inner join `class_ads` on `class_messages_chat`.ad_id = `class_ads`.id
    INNER JOIN `class_users` ON `class_users`.`id`=`class_ads`.`user_id`
    inner join `class_messages` on `class_messages_chat`.`chat_id` = `class_messages`.`chat_id`,
     (SELECT @rn:=1)rn,
     (SELECT @prev:=-1)prev
WHERE (   `class_messages_chat`.`to_user_id` = 133337
       or `class_messages_chat`.`from_user_id` = 133337)
and class_messages_chat.chat_id is not null
order by class_messages.id desc
) A
where A.Rn = 1 -- оставляем, все что с первым номером счетчика

Второй вариант для 5.7, если некорректно будет работать сортировка.
select B.*
from (SELECT A.*,
           IF(@prev <> A.chat_id, @rn:=1,@rn), @prev:= A.chat_id, @rn:=@rn+1 AS rn -- этой функцией нумеруем в пределах чата сообщения
from (
SELECT
      `class_messages_chat`.`to_user_id`,
       `class_messages_chat`.`from_user_id`,
       `class_users`.`id`,
       `class_users`.`user_status`,
       `class_users`.`online`,
       `class_messages_chat`.`chat_id`,
       `class_messages_chat`.`ad_id`,
       `class_ads`.user_id,
       `class_ads`.title
    FROM `class_messages_chat`
    inner join `class_ads` on `class_messages_chat`.ad_id = `class_ads`.id
    INNER JOIN `class_users` ON `class_users`.`id`=`class_ads`.`user_id`
    inner join `class_messages` on `class_messages_chat`.`chat_id` = `class_messages`.`chat_id`
WHERE (   `class_messages_chat`.`to_user_id` = 133337
       or `class_messages_chat`.`from_user_id` = 133337)
and class_messages_chat.chat_id is not null
order by class_messages.id desc
) A,
(SELECT @rn:=1)rn,
     (SELECT @prev:=-1)prev
) B
where B.Rn = 1 -- оставляем, все что с первым номером счетчика
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы