Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.05.22;
Скачать: CL | DM;

Вниз

Помогите с запросом   Найти похожие ветки 

 
Romkin ©   (2003-04-29 10:40) [0]

Давно уже пишу хранимые процедуры, запросы простые, а тут наткнулся на задачу, и застрял:
Есть таблица вида (ClientID, OrderID) - думаю, понятно, клиенты и документы.
Вывести запросом ClientID - номер клиента(тов!), которые выписали максимальное количество документов.
Например:

ClientID OrderID
1 23
1 46
5 62
5 48
5 81
24 46
34 89
34 13

Должно выдать 5
О выдаче количества речь не идет, нужен номер.
Проблема в том, что сделать нужно одним запросом на основе стандарта. Напоминаю: select top ... нет (и не подходит)
select from select нет, select max(count) - вложенные агрегатные функции недопустимы.
Вопрос: Можно ли написать подобный запрос, один, без использования view?


 
KoluChi ©   (2003-04-29 10:43) [1]

Select Max(Count(ClientID)) From Table
Group by ClientID


 
KoluChi ©   (2003-04-29 10:46) [2]

не то немного, сейчас соображу ... (может быть)


 
Соловьев ©   (2003-04-29 10:46) [3]


> KoluChi © (29.04.03 10:43)
> Select Max(Count(ClientID)) From Table
> Group by ClientID

а поле ClientID не надо разве в SELECT?


 
KoluChi ©   (2003-04-29 10:53) [4]

Мой вариант не проходит, нужно было внимательнее прочитать вопрос :)


 
Romkin ©   (2003-04-29 10:54) [5]

Говорю же - вложенные агрегаты недомустимы!


 
KoluChi ©   (2003-04-29 10:58) [6]

Пойдем логическим путем:
1) нужно вернуть 1 значение - сделать это можно только агр. функцией (max, count) в данном случае нужен max.
2) Максимум нужно искать из количества документов - количество документов - count(OrderID) для конкретного ClientID
3) Порядок сортировки не поможет (top тоже нет)
4) WHERE не знаю куда вставить
Получаем запрос с 2 вложенными группировками, если у нас нет SELECT FROM SELECT и MAX(COUNT), imho, одним запросом не обойтись.


 
Соловьев ©   (2003-04-29 11:01) [7]

Select ClientID, sum(OrderID) From Table
Group by ClientID
Order by ClientID desc


и взять первую запись


 
Romkin ©   (2003-04-29 11:01) [8]

А если group by & having добавить? во where & having подзапросы писать же можно...
top, кстати, в любом случае не подойдет - а если есть два ClientID с одинаковым максимальным количеством?


 
Соловьев ©   (2003-04-29 11:01) [9]

забыл :)))

Select ClientID, sum(OrderID) as SumOrd From Table
Group by ClientID
Order by SumOrd desc



 
Romkin ©   (2003-04-29 11:03) [10]

Суммировать OrderID?! И что получится?


 
KoluChi ©   (2003-04-29 11:04) [11]


> Соловьев © (29.04.03 11:01)

sum(OrderID) - получим что-то страшное :)


 
Соловьев ©   (2003-04-29 11:05) [12]

вот блин, читать надо было внимательно вопрос... сорри я подумал что OrderId это количество... сорри еще раз...


 
Соловьев ©   (2003-04-29 11:07) [13]

тогда так...
Select ClientID, count(ClientID) as CntCli From Table
Group by ClientID
Order by CntCli desc

и взять первую запись...


 
KoluChi ©   (2003-04-29 11:08) [14]


> Romkin © (29.04.03 11:01)
> а если есть два ClientID с одинаковым максимальным количеством?

Тогда моя лог. цепочка разбилась в пух и прах :)
>Соловьев © (29.04.03 11:01)
только всесто sum взять count и строки обрабатывать вручную


 
Соловьев ©   (2003-04-29 11:14) [15]


> и строки обрабатывать вручную

ну а че? если уж извращяться так по полной программе... :))))


 
Romkin ©   (2003-04-29 11:21) [16]

Select ClientID, count(ClientID) as CntCli From Table
Group by ClientID
having count(ClientID) = (Select top 1 count(ClientID) from Table group by ClientID order by count(ClientID) desc)
Теперь проблема - избавиться от этого самого top :-))


 
KoluChi ©   (2003-04-29 11:29) [17]


> Соловьев © (29.04.03 11:14)
>
> > и строки обрабатывать вручную
>
> ну а че? если уж извращяться так по полной программе...
> :))))

Почему извращаться, в любом случае нужно будет обрабатывать несколько строк с идентификаторами. Если конечно не найдете способ идентификаторы разместить по колонкам (вот это будут извращение :)


 
stone ©   (2003-04-29 11:30) [18]

view:
select clientid, count(orderid) as ordercount from table group by clientid
, а потом запрос

select client id from table where clientid in (select clientid from view where ordercount = (select max(ordercount) from view))

если пооптимизировать, то конструкцию in можно заменить на конструкцию exists


 
Соловьев ©   (2003-04-29 11:31) [19]


> Почему извращаться, в любом случае нужно будет обрабатывать
> несколько строк с идентификаторами

я имею ввиду, проверку, когда несколько клиентов будут иметь максимальное количество.


 
KoluChi ©   (2003-04-29 11:31) [20]

Select ClientID, count(ClientID) as CntCli From Table
Group by ClientID
having count(ClientID) = (Select count(ClientID) from Table group by ClientID order by count(ClientID) desc)
и не надо избавиться от этого самого top :-))



 
Romkin ©   (2003-04-29 11:35) [21]

2KoluChi А вот так не пойдет, при = < > подзапрос должен вернуть строго 1 строку


 
KoluChi ©   (2003-04-29 11:43) [22]

вместо = написать IN? Тогда вообще смысла нет.
остановимся на варианте Соловьев © (29.04.03 11:07)



 
Romkin ©   (2003-04-29 11:53) [23]

Yesss!!!
Select ClientID, count(ClientID) as CntCli From Table
Group by ClientID
having count(ClientID) not in (Select count(ClientID)-1 from Table group by ClientID)

Должно сработать!!! Или нет? Надо потестить


 
KoluChi ©   (2003-04-29 11:58) [24]

2Romkin © (29.04.03 11:53)
Ну ты мозг, оригинально, сам спросил - сам ответил.


 
Romkin ©   (2003-04-29 11:59) [25]

Только благодаря вам :-))
Не пофлеймишь - не поймешь :-)))


 
Соловьев ©   (2003-04-29 12:17) [26]

2 Romkin © (29.04.03 11:53)
супер-конечно, надо же сколько есть всяких способов.


 
Johnmen ©   (2003-04-29 14:44) [27]

>Romkin © (29.04.03 11:53)

Понятно, что такой запрос может давать некорректный результат...:)

Такой запрос однозначен :
SELECT T1.ClientID, COUNT(T1.ClientID)
FROM Table T1
GROUP BY T1.ClientID
HAVING COUNT(T1.ClientID) > ALL (SELECT COUNT(T2.ClientID)-1 FROM Table T2 GROUP BY T2.ClientID)


 
Romkin ©   (2003-04-29 14:59) [28]

Точно, спасибо :-))


 
Romkin ©   (2003-04-29 15:03) [29]

Кстати, могу сказать, что на мой запрос
Select ClientID, count(ClientID) as CntCli From Table
Group by ClientID
having count(ClientID) not in (Select count(ClientID)-1 from Table group by ClientID)
IB рушится:
internal gds software consistency check (EVL_expt: invalid operation (232))
А вот запрос Johnmen проходит, и дает правильный результат :-))


 
Johnmen ©   (2003-04-29 15:15) [30]

>Romkin © (29.04.03 15:03)
>IB рушится

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


 
Romkin ©   (2003-04-29 15:18) [31]

Если бы, буквально, твой запрос, стоит вместо "> ALL" поставить "NOT IN" - bugcheck :-(


 
Johnmen ©   (2003-04-29 15:26) [32]

Странно...Видимо, действительно, баг...:)
Проверил на WI-V6.2.908 Firebird 1.0 - нормально...


 
Romkin ©   (2003-04-29 15:34) [33]

Нормально?! IB5.6 & FB1.5 - баг. Можно смеяться



Страницы: 1 вся ветка

Текущий архив: 2003.05.22;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.015 c
1-70304
d_oleg
2003-05-13 09:38
2003.05.22
размер колонки TField в пикселях


3-70122
GAlex
2003-04-29 15:36
2003.05.22
Не пойму в чем косяк при создании временных таблиц


1-70318
zom
2003-05-07 15:02
2003.05.22
Окно, открываемое из сервиса. Как убрать его из таксбара?


1-70356
Tolik1
2003-05-09 16:33
2003.05.22
Размеры окон


1-70392
Vasiliy
2003-05-10 20:37
2003.05.22
Господа, подскажите как синхронизировать перерисовку Canvas