Не могу сделать order by перед group by. Вообще запрос несколько сложнее, там 4 таблицы задействованно, но для примера просто выдрал запрос к одной таблице. Например есть табилца в виде сообщений форума(forum_msgs) поля - id,topic_id,date,text Нужно сгруппировать поля по topic_id - и чтобы вывело последнее сообщение в нем data и текс. По логике нужен запрос типа. PHP: SELECT date, text, topic_id FROM forum_msgs GROUP BY topic_id ORDER BY topic_id,date DESC В результате в topic_id - выдает первое сообщение, а не последнее по дате, т.к. группирует перед ордером. Вариант есть PHP: SELECT max(date), text, topic_id FROM forum_msgs GROUP BY topic_id ORDER BY topic_id,date DESC Но тогда дату подтянет последнюю, но она не будет соответствовать своему тексу сообщения. Вообще в моем случае для нескольких таблиц делаю запросы типа - PHP: SELECT * FROM ( SELECT ........ ORDER BY .... ) p1 GROUP BY p1.dir_id но тут тоже ничего не выходит
Вам нужно при создании сообщения в таблице topic вставлять id последнего сообщения в теме. Тогда будет проще. Иначе всё становится не очень тривиальным и требует дополнительной нагрузки на сервер, что-то типа: PHP: SELECT t1.topic_id, (SELECT fm.text FROM forum_msgs fm WHERE fm.topic_id = t1.topic_id ORDER BY fm.date DESC LIMIT 1 ) as text FROM (SELECT DISTINCT topic_id FROM forum_msgs ORDER BY date DESC LIMIT 10 /*Кол-во топиков на странице*/ ) t1
Привет Тут пока о вставке сообщений речи не идет, просто никак не могу понять почему mysql выдает разные по сортировке таблицы в двух запросах типа. PHP: SELECT date, text, topic_id FROM forum_msgs ORDER BY topic_id,date DESC и в запросе типа. PHP: SELECT * FROM (SELECT date, text, topic_id FROM forum_msgs ORDER BY topic_id,date DESC) t1
Ну просто по логике программа в начале должна сделать этот запрос PHP: SELECT date, text, topic_id FROM forum_msgs ORDER BY topic_id,date DESC Построить отсортированную таблицу и уже ее передать Селекту, что выше уровнем. Просто применять GROUP BY уже бессмысленно, т.к. таблица передалась не отсортированной.. PHP: SELECT * FROM (SELECT date, text, topic_id FROM forum_msgs ORDER BY topic_id,date DESC) t1 GROUP BY topic_id В интернете только такие примеры и пишут, но не работает и все тут, может какие-то настройки в самом mysql надо поменять. хз
Логика может быть совсем другая. Например ORDER BY сортирует только "указатели" на записи и если нет вывода, то за скобками это естественно сбрасывается. Там очень много процессов по оптимизации выполнения и они не укладываются в простую логику, которую вы видите по тексту.
Вы ожидаете того, чего SQL не обязан делать. Вообще при группировке во фразе select должны быть только поля из фразы group by плюс агрегированные данные из других полей. То есть sum(), max() и т.п. https://php.ru/forum/threads/poisk-dvojnyx-zapisej-v-baze-dannyx.59235/#post-477442 MySql при некоторых настройках не выдаёт ошибку на запросы как у вас, но это не значит, что они правильные. Это бессмыслица. Непредсказуемый результат. Так как реляционная бд подразумевает работу с неупорядоченными наборами данных, любые наблюдаемые "закономерности" в выдаче неправильных группировок могут быть случайными и могут измениться после обновления движка или после бэкап+рестор. --- Добавлено --- Кроме айди темы в твоей таблице есть айди сообщения? Мне кажется выход в том, чтобы найти последние то есть max(post_id) и использовать их для добывания text. Запрос с подзапросом. --- Добавлено --- Но в целях оптимизации, как уже писали, в таблице "темы" заводят ссылки на эти самые последние post_id, чтобы избежать дорогостоящих группировок. Оптимизируют то, что чаще выполняется! Чтение на форуме работает намного чаще, чем запись. Поэтому оправданно при записи сообщения пойти на некоторую дополнительную работу - update таблицы темы.
мне тут немного подсказали, но запрос решил делать такого типа. Сразу вытаскивает все дерево форума и все подфорумы, находит в каждом подфоруме последнюю тему и последнее сообщение в этой теме(если есть), а также все количество тем и сообщений в каждом разделе. Не знаю как по времени будет это работать, если долго можно сохранять где-нибудь в кэш и каждую минуту обновлять, но с моим мини проектом думаю это будет лишним. Код (Text): SELECT t1.*, t2.title, t2.topic_id, t2.topic_date, t2.topic_user_id, t2.topic_user_name, t2.topic_user_login, t2.topic_user_logo, t2.msg_id, t2.msg_date, t2.msg_user_id, t2.msg_user_name, t2.msg_user_login, t2.msg_user_logo FROM( SELECT t1.parent_id, t1.id id, t1.name, t1.description, COUNT(*) msgs, COUNT(distinct title) titles FROM forum_dirs t1 LEFT JOIN forum_topics t2 ON t1.id=t2.dir_id LEFT JOIN forum_msgs t3 ON t3.topic_id=t2.id GROUP BY t1.id ORDER BY parent_id,pos ) t1 LEFT JOIN ( SELECT forum_topics.title, forum_topics.dir_id, forum_topics.id topic_id, forum_topics.date topic_date, forum_topics.user_id topic_user_id, users.logo topic_user_logo, users.name topic_user_name, users.login topic_user_login, t3.* FROM forum_topics LEFT JOIN users ON users.id=forum_topics.user_id LEFT JOIN ( SELECT forum_msgs.id msg_id, forum_msgs.user_id msg_user_id, forum_msgs.date msg_date, forum_msgs.topic_id msg_topic_id, users.logo msg_user_logo, users.name msg_user_name, users.login msg_user_login FROM forum_msgs LEFT JOIN users ON users.id=forum_msgs.user_id WHERE (topic_id, date) IN (SELECT topic_id, max(date) FROM forum_msgs GROUP BY topic_id) ) t3 ON t3.msg_topic_id=forum_topics.id WHERE (dir_id, date) IN (SELECT dir_id, max(date) FROM forum_topics GROUP BY dir_id) ) t2 ON t2.dir_id=t1.id
Бедный сервачок.. не жалеете вы железку К тому же это + несколько ватт энергии впустую, а это жизнь одной птички. А ведь она могла жить.. скоро весна. Индексы хоть создайте, чтобы полегче было