SQL MAX (m.time) не выбирает наибольшее значение

0

Кусок кода:

SELECT m.message, 
          MAX(m.time) AS time, 
          m.sender, 
          m.receiver, 
          m.contact, 
          u.ufirstname
FROM( (SELECT message, 
                  receiver_uid AS receiver, 
                  sender_uid AS sender, 
                  time, 
                  receiver_uid AS contact 
             FROM messages 
            WHERE sender_uid = '$me' ) 
           UNION 
           (SELECT message, 
                   receiver_uid AS receiver, 
                   sender_uid AS sender, 
                   time, 
                   sender_uid AS contact 
              FROM messages 
             WHERE receiver_uid = '$me' ) ) AS m, 
         users AS u
   WHERE m.contact = u.uid
GROUP BY m.contact
ORDER BY time DESC;

Моя проблема в том, что этой части СЛЕДУЕТ выбрать последнее сообщение о разговоре. Это формат базы данных:

Sender_uid | receiver_uid | message | time («What format should this be?)

Первая часть получает все сообщения, в которых участвует "$ me" (= userID зарегистрированного пользователя). Итак all сообщения, отправляемые или получаемые "$ me". Вторая часть должна выбрать самое последнее время (наибольшее значение) для каждого "разговора" (= идентификатор контакта, независимо от того, является ли контакт получателем или отправителем).

Он не получает последнее сообщение. Он делает дает вам одно сообщение из беседы.

Важная подсказка (?):. Я думаю, что script выполняет поиск последнего сообщения, где '$ me' является отправителем.

Я хочу, чтобы он собирал последнее сообщение: $me - приемник или отправитель.

Теги:

1 ответ

1
Лучший ответ

Пожалуйста, прекратите злоупотреблять MySQL с помощью агрегатов микширования и неагрегатов. Хотя MySQL позволяет это, непредсказуемо записывает каждый столбец, и они даже не должны быть из одной и той же записи (в синхронизации)

SELECT m2.message, 
          m2.time AS time, 
          m2.sender, 
          m2.receiver, 
          m.contact, 
          u.ufirstname
FROM (
    SELECT
        case when sender_uid = '$me' then receiver_uid else sender_uid end Contact,
        max(time) maxtime
    FROM messages 
    WHERE sender_uid = '$me' or receiver_uid = '$me'
    group by case when sender_uid = '$me' then receiver_uid else sender_uid end
) AS m
INNER JOIN messages m2 on m.maxtime = m2.time
    and ((m2.sender_uid = '$me' and m2.receiver_uid = m.Contact)
        or
        (m2.receiver_uid = '$me' and m2.sender_uid = m.Contact))
INNER JOIN users AS u on m.contact = u.uid
ORDER BY time DESC;

@updated query - сложнее, чем он выглядел.

  • "Контакт" - это другая сторона разговора.
  • Внутренний OR используется для однократного прохождения таблицы.
  • Внутренний оператор CASE используется для получения идентификатора другой стороны. Если "$ me" соответствует отправителю, приемник становится "контактом", в противном случае отправитель является "контактом"
  • Соединение с m2 использует 3 атрибута - меня, контакт (ориентация) и maxtime Это соединение использует ключи из внутреннего запроса (maxTime) для извлечения полная запись из таблицы
  • Существует окончательное соединение с пользователями, чтобы получить контакт firstname
  • 2
    Комментарий, а не ответ. Но я полностью согласен с тем, что мне не нравится «особенность» MySQL (и SQLite) в отношении возможности опускать предложения GROUP BY. Это хорошо для опытных разработчиков SQL
  • 0
    контакт не поле.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню