Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Составление SQL-запросов > [MySQL] Помогите составить запрос


Автор: hetfield 23.1.2012, 13:26
Добрый день. Есть таблица с новостями сайта. Все новости делятся на 10 категорий. То есть пример:


id    cat_id    title
1        2         заголовок новости
2        7         второй заголовок новости


Как мне за один (желательно) select вытащить по три последние новости с каждой категории... 

Автор: Zloxa 23.1.2012, 13:38
Код

select cat_id, title 
from (
  select cat_id,title,row_number() over (partion by cat_id,order by id desc) rn from news
) s
where rn < 3


однако ж, скорее всего у вас MySQL, а он не поддерживает синтаксиса SQL2003

Автор: hetfield 23.1.2012, 13:42
Да, MySQL. То есть ваш вариант там не сработает? А аналог для MySQL? )

Автор: Zloxa 23.1.2012, 13:51
Цитата(hetfield @  23.1.2012,  13:42 Найти цитируемый пост)
А аналог для MySQL? ) 

Можно и для MySQL и "одним запросом", но, думаю, вам следует отказаться от задумки получить это одним запросом непосредственно из таблицы новостей, а готовить новости для отображения загодя, непосредственно при добавлении оных. Кстати, весьма не тривиальная задача, есть о чем подумать, при условии, если новости могут добавляться в конкурентном режиме. 

Либо же из PHP в цикле обхода курсора по категориям, дергать по три записи из новостей, что, мне кажется, будет попроще.


Код

select *
from news t
where 3 < (select count(*) from news s where s.cat_id = t.cat_id and s.id > t.id)

Автор: hetfield 23.1.2012, 14:08
А почему советуете отказаться? "Тяжелый" запрос получается? 

Вы предлагаете, к примеру, сделать еще одну таблицу, в которую добавлять по мере создания новостей по три с каждой категории и потом уже спокойно одним запросом их брать с этой таблицы? 


Автор: Zloxa 23.1.2012, 14:16
Цитата(hetfield @  23.1.2012,  14:08 Найти цитируемый пост)
"Тяжелый" запрос получается? 

Тем тяжелее, чем больше объемы. Если же роста объемов не предполагается, то вполне себе решение.

Цитата(hetfield @  23.1.2012,  14:08 Найти цитируемый пост)
Вы предлагаете, к примеру, сделать еще одну таблицу, в которую добавлять по мере создания новостей по три с каждой категории и потом уже спокойно одним запросом их брать с этой таблицы? 

или же брать не одним запросом, а дергать по три записи для каждой категории. Но тут я толком не знаю сможет ли MySQL эффективно использовать составной индекс для сортировки по убыванию.

Автор: hetfield 23.1.2012, 14:21
Цитата

или же брать не одним запросом, а дергать по три записи для каждой категории


В моем случае 10 отдельных запросов. Это первое о чем я подумал, но мне кажется что так будет "тяжелей", чем ваш вариант


Цитата

может ли MySQL эффективно использовать составной индекс для сортировки по убыванию


Объясните что это, если не сложно? )

Автор: Zloxa 23.1.2012, 14:34
Цитата(hetfield @  23.1.2012,  14:21 Найти цитируемый пост)
Объясните что это, если не сложно? ) 

Как можно объяснить то- чего не знаешь?  smile 

Я уже не в первый раз делился этими сомнениями на этом форуме, но пока никто моих сомнений не развеял.

В вашем случае, если id определяет степень новизны новости, то для того, чтобы выбрать три наиболее новых новости по категории, было бы целесообразно использовать индекс по паре (cat_id,id). Если MySQL сумеет запрос "select * from news where cat_id = :cat_id order by id desc limit 3" свести к сканированию индекса по убыванию начиная со старшего id для заданной категории, с условием выхода по отбору трех записей, то снижение производительности 10 ваших запросов окажется не существенным даже при весьма и весьма существенном увеличении объемов. Только вот я не знаю умеет ли так мася. Оракл, знаю - умеет. А масю я  в глаза не видывал.

Автор: hetfield 23.1.2012, 14:39
В общем буду что-то пробовать. ) Спасибо за советы ))

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)