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

MySQL/PostgreSQL/SQLite/Oracle/M$SQL/....

Модератор: terminus

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Аватара пользователя
ProFTP
подполковник
Сообщения: 3388
Зарегистрирован: 2008-04-13 1:50:04
Откуда: %&й
Контактная информация:

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

Непрочитанное сообщение ProFTP » 2009-12-17 13:19:57

хотел вывести одим запросом ближайщие подкатегории, так сделано тут например: 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 
Pеrl FAQ
perl -e 'print join"",map $$_[rand@$_],([0..9,'a'..'z','A'..'Z'])x30'
ИзображениеИзображение

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35462
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

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

Непрочитанное сообщение Alex Keda » 2010-02-28 14:20:34

может сделать хранимку?
Убей их всех! Бог потом рассортирует...

Аватара пользователя
ProFTP
подполковник
Сообщения: 3388
Зарегистрирован: 2008-04-13 1:50:04
Откуда: %&й
Контактная информация:

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

Непрочитанное сообщение ProFTP » 2010-03-04 13:04:10

на 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 часа (прокешировать)
Pеrl FAQ
perl -e 'print join"",map $$_[rand@$_],([0..9,'a'..'z','A'..'Z'])x30'
ИзображениеИзображение

Аватара пользователя
Gamerman
капитан
Сообщения: 1723
Зарегистрирован: 2009-05-17 21:01:23
Откуда: Украина, Ужгород - Днепр
Контактная информация:

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

Непрочитанное сообщение Gamerman » 2010-03-11 21:53:13

А мускуль ругается на такой запрос?
Глюк глюком вышибают!

Аватара пользователя
ProFTP
подполковник
Сообщения: 3388
Зарегистрирован: 2008-04-13 1:50:04
Откуда: %&й
Контактная информация:

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

Непрочитанное сообщение ProFTP » 2010-03-12 18:42:23

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


я решил это по другому сделать, просто не оптимизиованный запрос, а потом прокешировать...
Pеrl FAQ
perl -e 'print join"",map $$_[rand@$_],([0..9,'a'..'z','A'..'Z'])x30'
ИзображениеИзображение

Аватара пользователя
Gamerman
капитан
Сообщения: 1723
Зарегистрирован: 2009-05-17 21:01:23
Откуда: Украина, Ужгород - Днепр
Контактная информация:

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

Непрочитанное сообщение Gamerman » 2010-03-12 20:48:55

С ходу могу предложить: использовать временную таблицу, созданную через запрос с лимит. По быстроте получится почти так же.
Глюк глюком вышибают!

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

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

Непрочитанное сообщение zg » 2010-03-13 21:46:48

ProFTP писал(а):(это как раз болшое преимущество PostgreSQL )
зачем поощрять кривые запросы?

Аватара пользователя
ProFTP
подполковник
Сообщения: 3388
Зарегистрирован: 2008-04-13 1:50:04
Откуда: %&й
Контактная информация:

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

Непрочитанное сообщение ProFTP » 2010-03-14 7:00:13

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
Pеrl FAQ
perl -e 'print join"",map $$_[rand@$_],([0..9,'a'..'z','A'..'Z'])x30'
ИзображениеИзображение

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

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

Непрочитанное сообщение zg » 2010-03-14 13:03:47

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