Вывести 10 последних уникальных записей

evshi

Новичок
Есть таблица, которая хранит в себе поисковые запросы. Мне надо вывести 10 последних уникальных запросов (к сожалению некоторые запросы дублируются). Пытаюсь так:
SELECT DISTINCT (
`needle`
)
FROM `search`
ORDER BY `dt` DESC
LIMIT 10

При таком запросе выводятся не последние 10, а 10, но в каком-то непонятном порядке.

Например, вывожу через запрос последние 10 добавленных записей:
SELECT `needle` FROM `search` ORDER BY `dt` DESC LIMIT 10
Получаю:
вакансия
вакансия
духи
духи
духи
lotos
центр аудита и консалтинга финаудит
lotos
lotos
энтузиаст

Затем делаю
SELECT DISTINCT (
`needle`
)
FROM `search`
ORDER BY `dt` DESC
LIMIT 10

Получаю:
духи
lotos
tecnopack.ru
PUTZMEISTER
Алармстройсервис
Тепло Уют Сервис
производство
лдсп
lateral.ru
mappaper.ru

Куда делись центр аудита и консалтинга финаудит и энтузиаст?:(
 

prolis

Новичок
Приведи версию сервера и структуру таблиц. Возможно чудит с сортировкой из-за неправильной кодировки.
 

prolis

Новичок
"Если LIMIT # указывается совместно с DISTINCT, MySQL остановится, как только найдет # уникальных строк."
 

evshi

Новичок
Приведи версию сервера и структуру таблиц. Возможно чудит с сортировкой из-за неправильной кодировки.
MySQL: 5.0.51a.

CREATE TABLE `search` (
`id` int(11) NOT NULL auto_increment,
`needle` varchar(255) default NULL,
`obj_type` tinyint(1) default NULL,
`referer` varchar(255) default NULL,
`resultQnt` int(11) default NULL,
`ip` varchar(16) NOT NULL,
`dt` datetime default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=35928 ;

Сделал экспорт части записей на локальную машину - там работает как надо:(
 

whirlwind

TDD infected, paranoid
evshi повторяю: limit + distinct = сначала лимит, затем сортировка. На пальцах это значит что сначала mysql в "неопределенном" порядке выбирает записи, когда набирает 10 уникальных закрывает выборку и уже потом сортирует. В кавычках потому что определить порядок можно, но не нужно, ибо хак. А тебе надо наоборот - применить лимит на отсортированные записи, что с дистинктом не работает. Ищи другое решение.

PS. попробуй индекс DESC на dt сделать
 

evshi

Новичок
evshi повторяю: limit + distinct = сначала лимит, затем сортировка. На пальцах это значит что сначала mysql в "неопределенном" порядке выбирает записи, когда набирает 10 уникальных закрывает выборку и уже потом сортирует. В кавычках потому что определить порядок можно, но не нужно, ибо хак. А тебе надо наоборот - применить лимит на отсортированные записи, что с дистинктом не работает. Ищи другое решение.

PS. попробуй индекс DESC на dt сделать
Вах, оказывается вы правы! Здесь http://bugs.mysql.com/bug.php?id=33087 обсуждают этот вопрос + есть несколько решений. Спасибо!
 

zerkms

TDD infected
Команда форума
PS. попробуй индекс DESC на dt сделать
whirlwind
оно игнорится до сих пор :)

An index_col_name specification can end with ASC or DESC. These keywords are permitted for future extensions for specifying ascending or descending index value storage. Currently, they are parsed but ignored; index values are always stored in ascending order.
(с) http://dev.mysql.com/doc/refman/5.1/en/create-index.html
 

evshi

Новичок

evshi

Новичок
Решение с индексом мне нравится больше всего. Только вот объясните, пожалуйста, как оно работает:)? Почему после добавления индекса, SQL начинает правильно сортировать?

И второй вопрос: к сожалению не разбирался подробно в тонкостях USING BTREE, но почему в примере приводят именно его?
 

whirlwind

TDD infected, paranoid
evshi оно не требуется в типовых случаях. Не факт что он индекс этот подцепит. Не факт что в дальнейшем поведение не изменится. Как я намекал - грязные хаки для хакеров, а не для разработчиков.
 

Vin-Diesel

Новичок
А так чего не работает?
CREATE TABLE search (needle varchar(10) not null, dt datetime not null);
insert into search values('вакансия', now()),('вакансия', now()),('духи', now()),('духи', now()),('духи', now()),('lotos', now()),('центр ау', now()),('lotos', now()),('lotos', now()),('энтузиаст', now());
select needle from search group by needle order by dt desc;
select needle from search group by needle order by dt desc limit 2;
select needle from search group by needle order by dt desc limit 1,1;
 
Сверху