Страница 1 из 1

сложный запрос UNION JOIN обойти LIMIT

Добавлено: 2009-12-17 13:19:57
ProFTP
хотел вывести одим запросом ближайщие подкатегории, так сделано тут например: http://yaca.yandex.ru/yca/cat/Entertainment/

категори: Игры
подкатегории: 3D-шутеры, RPG, стратегии, Флеш-игры ...

работает

Код: Выделить всё

SELECT t3.id_se, t3.name_se, t3.parent_se_id
        FROM section AS t3
        WHERE t3.parent_se_id = 1
        
        
        UNION ALL
  
        SELECT t1.id_se, t1.name_se, t1.parent_se_id
            FROM  section AS t1 
            WHERE
          t1.parent_se_id = t3.id_se
НО хочу сделать чтобы был LIMIT 3 в подкатегориях, в данном случае не получается это сделать...



есть задачка http://habrahabr.ru/blogs/mysql/44807/
Есть новостной блоггерный сайт. Есть такие сущности как новости и комментарии к ним.

Задача — нужно написать запрос, который выводит список из 10 новостей определенного типа (задается пользователем) отсортированные по времени издания в хронологическом порядке, а также к каждой из этих новостей показать не более 10 последних коментариев, т.е. если коментариев больше — показываем только последние 10.
решение

Код: Выделить всё

CREATE TABLE `news` (
`id` int(11) NOT NULL auto_increment,
`date` datetime NOT NULL,
`title` varchar(200) NOT NULL,
PRIMARY KEY (`id`),
KEY `date` (`date`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `comment` (
`id` int(11) NOT NULL auto_increment,
`news_id` int(11) NOT NULL,
`date` datetime NOT NULL,
`body` varchar(200) NOT NULL,
PRIMARY KEY (`id`),
KEY `news` (`news_id`,`date`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Код: Выделить всё

SELECT n. *, c. *
FROM (
SELECT *
FROM news
WHERE
type = 2
ORDER BY date DESC
LIMIT 10
) as n
INNER JOIN (
SELECT *
FROM comments
WHERE
comments.news_id IN (
SELECT news.id
FROM news
WHERE
type = 2
ORDER BY date DESC
)
ORDER BY date DESC
LIMIT 10
) AS c
ON c.news_id = n.id 

как сюда прикрутить мой вариант

вот я пробовал - не хочет....

Код: Выделить всё

SELECT n. *, c. *
FROM (
SELECT *
FROM section as t1


LIMIT 10
) as n
INNER JOIN (
SELECT *
FROM section as t2
WHERE
t2.id_se IN (
SELECT t3.id_se
FROM section as t3


)

LIMIT 10
) AS c
ON c.id_se = n.parent_se_id 

Re: сложный запрос UNION JOIN обойти LIMIT

Добавлено: 2010-02-28 14:20:34
Alex Keda
может сделать хранимку?

Re: сложный запрос UNION JOIN обойти LIMIT

Добавлено: 2010-03-04 13:04:10
ProFTP
на PostgreSQL это делется очень просто (это как раз болшое преимущество PostgreSQL )

Код: Выделить всё

select *
  from (select * from news order by date desc limit 10) n
  join comments c on (c.news_id = n.id)
 where c.id in (
     select id from comments c1 where c1.news_id = n.id order by c1.date desc limit 10
 )
 order by n.date desc, c.date desc
как это сделать в хранимке? это в хранимке можно? на хабра-хабре это не обсуждают почему-то...

нужно не просто перебрать данные (перебрать в тупую все данные), а именно сделать такой запрос... и + у меня еще усложненно что древовидная структура, запарился с этим, решил как нибудь по другому сделать, закешировать, например, сделать как нибудь, а сам запрос прокеширвоать на 2 часа например

в прицнипе, пофиг можно сделать 40 запросов за 3 часа (прокешировать)

Re: сложный запрос UNION JOIN обойти LIMIT

Добавлено: 2010-03-11 21:53:13
Gamerman
А мускуль ругается на такой запрос?

Re: сложный запрос UNION JOIN обойти LIMIT

Добавлено: 2010-03-12 18:42:23
ProFTP
Gamerman писал(а):А мускуль ругается на такой запрос?
и в mysql5 этого нету и в mysql6, тоже

Код: Выделить всё

This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'»
http://dev.mysql.com/doc/refman/4.1/pt/ ... rrors.html
http://dev.mysql.com/doc/refman/6.0/en/ ... errors.htm


я решил это по другому сделать, просто не оптимизиованный запрос, а потом прокешировать...

Re: сложный запрос UNION JOIN обойти LIMIT

Добавлено: 2010-03-12 20:48:55
Gamerman
С ходу могу предложить: использовать временную таблицу, созданную через запрос с лимит. По быстроте получится почти так же.

Re: сложный запрос UNION JOIN обойти LIMIT

Добавлено: 2010-03-13 21:46:48
zg
ProFTP писал(а):(это как раз болшое преимущество PostgreSQL )
зачем поощрять кривые запросы?

Re: сложный запрос UNION JOIN обойти LIMIT

Добавлено: 2010-03-14 7:00:13
ProFTP
Gamerman писал(а):С ходу могу предложить: использовать временную таблицу, созданную через запрос с лимит. По быстроте получится почти так же.
я забыл написать что мне это срочно не нужно, я хотел тут сделать такой функционал как у яндекса http://www.x0.org.ua/view_global_section
потом нашел, эту статью на хабрахабре...

я решил, просто вытащить, и потом в цикле сделать пару дополнительных запрос (всего около 50-200), сформулировать хэш и и добавить в memcache на 2 часа например (чтобы это выплнялось на чаще чем 2 часа)
zg писал(а):
ProFTP писал(а):(это как раз болшое преимущество PostgreSQL )
зачем поощрять кривые запросы?
как в моем случае с parent_id написать, и чтобы было не "кривые" еще?
на хабрахабре на много легче задание, но том тоже не могли решить и там тоже сделали с помощю вложенных на mysql, вроде бы еще хуже

на pgsql один вложенный, который вытаскивает 10 элементов select * from news order by date desc limit 10

ЗЫ: но я уже решил сделать т.к. я написал выше в memcache добавить чтобы все время не выполнять

вот кстате на давно, тоже, был интересный запросег http://forum.lissyara.su/viewtopic.php?f=11&t=24622

Re: сложный запрос UNION JOIN обойти LIMIT

Добавлено: 2010-03-14 13:03:47
zg
ProFTP писал(а):как в моем случае с parent_id написать, и чтобы было не "кривые" еще?
два простых запроса - один на выьор списка новостей, второй - в цикле по новостям выбор комментариев. По производительности будет тожесамое, по логике намного проще.