Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: выборка в выборку  (Прочитано 15654 раз)
0 Пользователей и 3 Гостей смотрят эту тему.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« : 19-08-2010 06:26 » 

Есть таблица категорий, есть таблица статей

Нужно выбрать 10 последний статей из каждой категории

1.SELECT cat_name, cat_id FROM cat
2. и потом в цикле делать
SELECT * FROM article WHERE cat_id = $cat_id LIMIT 10

задумался... А можно ли это в один запрос впихнуть?
типа
select article.*
from article
left join cat on article.cat_id=cat.cat_id
order by cat_id

Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 19-08-2010 06:44 » 

мысль в сторону...
можно ли в конструкции  having использовать вычисления?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #2 : 19-08-2010 08:18 » 

Sla, есть правильное, но не работающее решение Улыбаюсь
Код: (SQL)
SELECT article.*, cat.* FROM article, cat
WHERE cat.cat_id IN (SELECT c.cat_id FROM cat c WHERE article.cat_id=c.cat_id ORDER BY 1 LIMIT 10)
К сожалению, для MySQL < 5.1 вернется ошибка:
Код: (Text)
Error Code: 1235
This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

Источник: http://stackoverflow.com/questions/494974/limiting-an-sql-join
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 19-08-2010 09:25 » 

Цитата: Sla
можно ли в конструкции  having использовать вычисления?
Так же, как и в where, плюс функции агрегирования.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 19-08-2010 09:44 » 

Вот надыбал такое Топ из Группы
http://www.artfulsoftware.com/infotree/queries.php?&bw=1275#104
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #5 : 19-08-2010 11:26 » 

Sla, решение в создании временной таблицы? Или дополнительной процедуры? Я так понимаю, нужно было исключительно через select-запросы, причем, желательно, запрос пошустрее..
Что у тебя получилось-то?
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 19-08-2010 11:51 » 

я сейчас проверить не могу, интересно посмотреть план запроса, и сравнить скорость выполнения
Через курсор (первое что пришло в голову), через динамический запрос (по моей ссылке) и твой пример
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 19-08-2010 13:52 » 

Если я понял правильно, там, по ссылке, предлагают сделать через процедуру. В общем-то, разумный выход без специфичного запроса. Просто перенос логики с клиента на сервер.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #8 : 19-08-2010 14:34 » new

Просто стало интересно. Решение для Oracle.

Код:
create table sla_cat(id number, name varchar2(64))
create table sla_art(id number, cat_id number, name varchar2(64))

insert into sla_cat values(1,'first')
insert into sla_cat values(2,'second')
insert into sla_cat values(3,'third')

insert into sla_art values(1,1,'article1_from_cat1')
insert into sla_art values(2,1,'article2_from_cat1')
insert into sla_art values(3,1,'article3_from_cat1')
insert into sla_art values(4,1,'article4_from_cat1')
insert into sla_art values(5,1,'article5_from_cat1')
insert into sla_art values(6,1,'article6_from_cat1')
insert into sla_art values(7,1,'article7_from_cat1')
insert into sla_art values(8,1,'article8_from_cat1')
insert into sla_art values(9,1,'article9_from_cat1')
insert into sla_art values(10,1,'article10_from_cat1')
insert into sla_art values(11,2,'article1_from_cat2')
insert into sla_art values(12,2,'article2_from_cat2')
insert into sla_art values(13,2,'article3_from_cat2')
insert into sla_art values(14,2,'article4_from_cat2')
insert into sla_art values(15,3,'article1_from_cat3')
insert into sla_art values(16,3,'article2_from_cat3')


Код:
select * from SLA_ART a
where a.ID in (
                select
                max(a.ID) keep (dense_rank last order by a.ID) over(partition by a.CAT_ID)rn from SLA_ART a
              )
union
select * from SLA_ART a
where a.ID in (
                select
                max(a.ID-1) keep (dense_rank last order by a.ID) over(partition by a.CAT_ID)rn from SLA_ART a
            )

max(a.ID-1) - цифрой управляем насколько старые статьи мы хотим увидеть.

Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
HandKot
Молодой специалист

ru
Offline Offline

« Ответ #9 : 20-08-2010 05:01 » 

тоже решил попробовать
код для MSSQL, применимость для MySQL не знаю

Код:
--для 2000
select
c.cat_name
, c.cat_id
, a.article_name
from
@cat C
left join @article a on a.cat_id=c.cat_id
left join @article a1 on a1.cat_id=c.cat_id and a1.article_name <= a.article_name
group by
c.cat_name
, c.cat_id
, a.article_name
having
count(a1.cat_id) <= 5

Код:
--для 2005 и выше
--используя CTE
;with mycte(cat_name, cat_id, article_name, rn)
as (
select
c.cat_name
, c.cat_id
, a.article_name
, row_number() over (partition by c.cat_id order by a.article_name) rn
from
@cat C
left join @article a on a.cat_id=c.cat_id)
select
*
from
mycte
where
rn <= 5

--используя CROSS APPLY
select
*
from
@cat C
cross apply (select top 5 * from @article a where a.cat_id=c.cat_id) a
Записан

I Have Nine Lives You Have One Only
THINK!
McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #10 : 20-08-2010 08:08 » 

Оптимизировал!


Код:
select results.id, results.cat_id, results.name from
(
    select a.*, dense_rank() over(partition by a.cat_id order by a.id desc) rnk from SLA_ART a
) results
where rnk <= 2

where rnk <= 2 - управляем количеством выводимых статей.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 20-08-2010 14:25 » 

Цитата: HandKot
тоже решил попробовать
код для MSSQL, применимость для MySQL не знаю
В самом начале baldr приводил элементарное решение, работающее для MS SQL Server. Только вместо limit нужно взять top.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #12 : 21-08-2010 14:11 » 

Dimka, а планы? Ага
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 21-08-2010 19:53 » 

McZim, план для группировки почти постоянный, план с in-подзапросом прямо зависит от количества отбираемых в подзапросе членов. На небольших N подзапрос лучше группировки, на больших N - наоборот.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
HandKot
Молодой специалист

ru
Offline Offline

« Ответ #14 : 23-08-2010 04:37 » 

Для Dimka
думаю, что EXISTS будет быстрее IN
Записан

I Have Nine Lives You Have One Only
THINK!
McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #15 : 23-08-2010 06:50 » 

Dimka, я к тому что там используются join, хотя можно обойтись и без него!
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines