Агрегирование результатов объединения, которые я также использую в предложении where с MySQL - PullRequest
0 голосов
/ 23 октября 2011

Я ссылаюсь на две таблицы в программном обеспечении веб-форума для простых машин: smf_members и smf_members.каждая строка в smf_members имеет поле: id_group, значения которого меня интересуют: 1,9,20,26,23,27 (с помощью предложения IN ()).Общая цель состоит в том, чтобы определить, какие строки в таблице smf_members, которые находятся в идентификаторах вышеуказанной группы, не вводили строку в smf_messages в течение 90 дней.poster_time в smf_messages - это метка времени Unix.На данный момент у меня есть:

SELECT
  m.id_member,
  m.id_group,
  from_unixtime(max(ms.poster_time))
FROM
  smf_members m
  LEFT JOIN smf_messages ms
    USING(id_member)
WHERE
  max(ms.poster_time) < (NOW() < (86400 * 90)
GROUP BY
  m.id_member

С ошибкой и ОШИБКА 1111: Неправильное использование групповой функции, так как я использую max () в предложении where.Как я могу агрегировать свои результаты объединения, чтобы ссылаться только на последнюю запись на основе поля poster_time?

Ответы [ 2 ]

0 голосов
/ 23 октября 2011

Есть несколько способов сделать это.

  1. ВЫБРАТЬ * ОТ участников ГДЕ id_member IN (...) И НЕ СУЩЕСТВУЕТ (ВЫБЕРИТЕ 1 ИЗ сообщений ГДЕ is_member = members.id_member AND poster_time> (UNIX_TIMESTAMP * () - 90 * 24 * 60 * 60)

  2. ищите случаи, когда внешнее соединение ничего не находит ВЫБЕРИТЕ DISTINCT id_member ОТ ЧЛЕНОВ КАК М ... LEFT JOIN сообщения, как MSG использования ГДЕ msg.id НЕДЕЙСТВИТЕЛЕН

  3. ВЫБРАТЬ * ОТ участников ГДЕ id_member IN (....) И id_member NOT IN (ВЫБЕРИТЕ id_member ИЗ сообщений ГДЕ poster_time> (UNIX_TIMESTAMP * () - 90 * 24 * 60 * 60) )

0 голосов
/ 23 октября 2011

Вы можете попробовать использовать временную таблицу, чтобы выяснить max(ms.poster_time) перед попыткой GROUP BY.Нечто подобное должно работать.

SELECT * FROM 
(SELECT
  m.id_member,
  m.id_group,
  from_unixtime(max(ms.poster_time))
FROM
  smf_members m
  LEFT JOIN smf_messages ms
    USING(id_member)
WHERE
  max(ms.poster_time) < (NOW() < (86400 * 90) ) AS tmp

GROUP BY
  m.id_member

Делая это таким образом, вы можете использовать функцию агрегирования с GROUP BY.Это не будет очень хорошо работать, если у вас есть большие наборы данных.Если это так, вы можете рассмотреть возможность регулярного суммирования данных, сгенерированных внутренней таблицей, а затем запрашивать их.

...