За последние 24 часа нас посетил 22661 программист и 1281 робот. Сейчас ищут 782 программиста ...

Помогите правильно составить запрос

Тема в разделе "MySQL", создана пользователем at0m1x, 31 янв 2012.

  1. at0m1x

    at0m1x Активный пользователь

    С нами с:
    18 дек 2011
    Сообщения:
    31
    Симпатии:
    0
    Всем привет! В mysql базе данных моего сайта есть таблица сообщений - переписка пользователей друг с другом. Таблица имеет следующие поля:

    Код (Text):
    1.  
    2. message_id | sender_id | recepient_id | subject | message | time
    В этой таблице содержится 4000000 записей. Мне необходимо из нее выбрать последние сообщения всех пользователей. Я пробовал делать выборку таким запросом:

    Код (Text):
    1.  
    2. SELECT `sender_id`, `subject`, `message`, `time`
    3. FROM `messages`
    4. GROUP BY `sender_id`
    5. ORDER BY `time` DESC
    Запрос ошибок не выдает, выбирает по одному сообщению для каждого пользователя, но при проверке оказалось что он выбирает не последние сообщения. Подскажите в чем может быть ошибка и как правильно составить такой запрос.
     
  2. yuri

    yuri Активный пользователь

    С нами с:
    16 янв 2012
    Сообщения:
    288
    Симпатии:
    2
    Это всё из-за GROUP BY, сделай в два запроса:
    SELECT DISTINCT id, `sender_id` FROM `messages` ORDER BY `time` DESC
    а потом имея ID вытащи сами тексты.

    Если операция частая, то ябы переделал структуру так, чтобы ID последнего сообщения хранился в свойствах пользователя, или еще где :)
     
  3. AndreJM

    AndreJM Активный пользователь

    С нами с:
    25 янв 2012
    Сообщения:
    522
    Симпатии:
    0
    Код (Text):
    1.  
    2. SELECT sender_id, subject, message, time
    3.  FROM (
    4.     SELECT sender_id, subject, message, time, IF(sender_id = @sender, 0, 1) grouper, @sender := sender_id
    5.     FROM messages, (select @sender := null) chao
    6.     ORDER BY sender_id, time desc) byebye
    7. WHERE grouper = 1
     
  4. yuri

    yuri Активный пользователь

    С нами с:
    16 янв 2012
    Сообщения:
    288
    Симпатии:
    2
    Выполни это на таблице в 4 000 000 записей.
     
  5. AndreJM

    AndreJM Активный пользователь

    С нами с:
    25 янв 2012
    Сообщения:
    522
    Симпатии:
    0
    Не вижу препятствий. Топик стартер не говорил, что требуется высокая скорость и оптимально оптимизированный запрос.
    Я лишь показал как это возможно сделать, а уже автору решать надо ему это или нет.
     
  6. asokol

    asokol Активный пользователь

    С нами с:
    17 янв 2012
    Сообщения:
    162
    Симпатии:
    0
    Код (Text):
    1. SELECT * FROM (
    2.     SELECT `sender_id`, `subject`, `message`, `time`
    3.     FROM `messages`
    4.     ORDER BY `time` DESC
    5. ) `m`
    6. GROUP BY `sender_id`
    7. ORDER BY `time` DESC;
    Код (Text):
    1. SELECT `sender_id`, `subject`, `message`, `time` FROM `messages` `m`
    2. WHERE `time`=(SELECT MAX(`time`) FROM `messages` WHERE `sender_id`=`m`.`sender_id`)
    3. ORDER BY `time` DESC
    - в данном случае лучше в WHERE заменить time на message_id, если между ними прямо пропорциональная связь.

    P.S. на скорость не тестировалось, но второй запрос медленнее по понятным причинам.
     
  7. AndreJM

    AndreJM Активный пользователь

    С нами с:
    25 янв 2012
    Сообщения:
    522
    Симпатии:
    0
    К сожалению Ваш запрос выдаёт результат который не соответствует задаче.
    MIN(`time`) - замените на MAX(`time`)
     
  8. asokol

    asokol Активный пользователь

    С нами с:
    17 янв 2012
    Сообщения:
    162
    Симпатии:
    0
    Спасибо, поправил.