Странный ответ в сортировке

Статус
В этой теме нельзя размещать новые ответы.

Denixxx

Мой дом здесь!
Регистрация
7 Фев 2014
Сообщения
244
Реакции
216
Пишу чат для своей ЦМС.
Столкнулся со странным поведением запроса.
Как его ни пиши:
1.
Код:
SELECT `id`,`time`,COUNT(`id`) AS cnt FROM chat_messages ORDER BY `time` ASC LIMIT 1;

2.
Код:
SELECT `id`,`time`,COUNT(`id`) AS cnt FROM chat_messages ORDER BY `time` DESC LIMIT 1;

Два запроса вроде разные (сортировка ASC или DESC), а ответ БД один и тот же:
PHP:
array (
0 =>
array (
'id' => '4',
'time' => '2014-11-18 19:11:43',
'cnt' => '100',
),
)
Для чего это: в чате хочу сделать ограничение по количеству сообщений в БД.
И если сообщений меньше положенного, делаю INSERT, иначе — UPDATE самого старого сообщения.
И вот такое странное поведение затирает позже первое попавшееся сообщение, даже если оно свежее. А мне нужно выбрать id самого старого.
 
Может там только это сообщение и есть? :)

Выложи дамп базы, интересно глянуть. Вообще с сортировкой по дате никогда не встречал проблем.
 
Может там только это сообщение и есть?
Ну как же одно, когда счётчик COUNT(`id`) = 100 (см. вывод)?
В том-то и дело, что сортировка как-бы не работает, дергается первое попавшееся из БД:
Запрос select * from chat_messages
Результат
Код:
array (
0 =>
array (
'id' => '4',
'username' => 'Den',
'nickname' => 'Den1xxx',
'avatar' => 'content/avatars/Den.gif',
'channel' => 'general',
'message' => 'новый баг',
'time' => '2014-11-18 19:11:43',
),
1 =>
array (
'id' => '5',
'username' => 'Den',
'nickname' => 'Den1xxx',
'avatar' => 'content/avatars/Den.gif',
'channel' => 'general',
'message' => 'решил и этот',
'time' => '2014-11-18 19:40:59',
),
2 =>
array (
'id' => '3',
'username' => 'Den',
'nickname' => 'Den1xxx',
'avatar' => 'content/avatars/Den.gif',
'channel' => 'general',
'message' => 'ddd',
'time' => '2014-11-18 19:40:48',
),
и т.д. 100 записей.
Разбиваю запрос на 2 — всё работает корректно:)
Пока разбил на 2 запроса, но это не кошерно:)
Структура БД тоже не тайна:
Код:
CREATE TABLE `chat_messages` (
  `id` int(5) NOT NULL auto_increment,
  `username` varchar(200) NOT NULL,
  `nickname` varchar(200) NOT NULL,
  `avatar` varchar(200) NOT NULL,
  `channel` varchar(200) NOT NULL,
  `message` text NOT NULL,
  `time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
Давайте весь код, не в запросе у вас ошибка. Скорее всего либо не ту переменную выводите, либо еще что.
 
Давайте весь код, не в запросе у вас ошибка. Скорее всего либо не ту переменную выводите, либо еще что.
Ошибка именно в запросе.
Внутри движка у меня есть спец. инструмент, с помощью которого я могу это проверить:
sort_desc.png sort_asc.png
Короче если стоит выборка по COUNT, сортировка не сортирует
 
Любезнейший, а не сделаете ваш запрос без этого фрагмента " LIMIT 1 " ?
Сразу прояснится проблема, быть может?
ну и итог - заранее
1) count - группировочная функция, и все ваши сортировки ей пофигу - она берет физически первую запись для вывода, а в более ранних версиях MySQL - вообще исключение в вашем запросе бы выдала
2) даже с учетом возможности действия (а можно сделать вложенный запрос, или с JOIN - с каунтером) - запрос будет в разы (на порядки) медленнее на большой таблице, чем если бы вы сделали 2 запроса - на поиск и на счетчик раздельно
3) ничего странного - все как надо - не ленитесь :D

но уж если очень охота, шо невмоготу:
SELECT `id`,`time`, cm2.cnt FROM chat_messages AS cm1
LEFT JOIN
(SELECT COUNT(*) AS cnt FROM chat_messages) AS cm2
ON 0=0
ORDER BY cm1.`time` ASC LIMIT 1;

:crazy: как-то так
 
Последнее редактирование:
Любезнейший, а не сделаете ваш запрос без этого фрагмента " LIMIT 1 " ?
Сразу прояснится проблема, быть может?
ну и итог - заранее
1) count - группировочная функция, и все ваши сортировки ей пофигу - она берет физически первую запись для вывода, а в более ранних версиях MySQL - вообще исключение в вашем запросе бы выдала
2) даже с учетом возможности действия (а можно сделать вложенный запрос, или с JOIN - с каунтером) - запрос будет в разы (на порядки) медленнее на большой таблице, чем если бы вы сделали 2 запроса - на поиск и на счетчик раздельно
3) ничего странного - все как надо - не ленитесь :D

но уж если очень охота, шо невмоготу:
SELECT `id`,`time`, cm2.cnt FROM chat_messages AS cm1
LEFT JOIN
(SELECT COUNT(*) AS cnt FROM chat_messages) AS cm2
ON 0=0
ORDER BY cm1.`time` ASC LIMIT 1;

:crazy: как-то так
Спасибо. Единственный вменяемый ответ, поясняющий суть происходящего.
Конечно, я уже давно разбил на 2 запроса, ибо они работают корректно:
Код:
SELECT COUNT(`id`) AS cnt FROM chat_messages;
SELECT `id` FROM chat_messages ORDER BY `time` ASC LIMIT 1;
А раз Вы говорите, что это будет ещё и быстрее работать, то и ладно:)
Еще раз спасибо, что помогли разобраться — это всегда полезно.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху