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

Группировка

Добавлено: 25 апр 2006, 11:31
Senya
Часто возникает задача такого рода: Есть для примера таблица содержащая код обьекта, время и количество. Необходимо для каждой группы объектов найти количество выдававшееся последним. В Аксесе я делал так
Select Cod, Last(Count) from Table
Group by Cod
Order by Max(Time)
Как подобную задачу красиво решить в ibase , как я понимаю агрегатные функции Last() и First() есть только в Аксесе?

Добавлено: 25 апр 2006, 12:33
Ivan_Pisarevsky

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

Select t1.Cod, 
  max(t1.fTime), 
  (select fcount 
   from table t2 
   where t1.cod = t2.cod and t2.ftime = max(t1.ftime)) as fcount
from Table t1 
Group by t1.Cod 
Order by 2 

Добавлено: 25 апр 2006, 12:39
Senya
Спасибо.

Добавлено: 25 апр 2006, 13:34
Senya
Предлоенный запрос
Ivan_Pisarevsky писал(а):

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

Select t1.Cod, 
  max(t1.fTime), 
  (select fcount 
   from table t2 
   where t1.cod = t2.cod and t2.ftime = max(t1.ftime)) as fcount
from Table t1 
Group by t1.Cod 
Order by 2 
Представляет обычное внутреннее обьеденение и даже при не очень большой таблице N = 5000 записей делает N^2 вычислений а с учетом того что во внутреннем запросе max(t1.ftime) будет пересчитываться каждый раз - так что даже N^3. Я подождал пол часа но ответа на запрос так и не получил. А в Аксесе почти мгновенно. Не ужели на таком мощном сервере как firebird не найдется более красивого решения. Можно конечно сделать внешнее:
select .. from Table T1 Left Join(Select ..from Table T2 Group by ..) On ...
Но подобные конструкции появились только в FireBird 2.0 , а на нем не работает нужное мне ПО.
Access Forever!!!

Добавлено: 25 апр 2006, 14:58
eg
Senya писал(а):...
на таком мощном сервере
...
а какой именно сервер?

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

Select t1.Cod, 
  (select first 1 t2.fcount 
   from table t2 
   where t1.cod = t2.cod 
   order by t2.fTime desc) as fcount
from Table t1 
Group by t1.Cod
Senya писал(а): Access Forever!!!
Уря

Добавлено: 25 апр 2006, 16:55
Ivan_Pisarevsky

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

oCod = NULL;
otime = NULL;
ocount = NULL;
for Select t1.Cod,t1.ftime, t1.fcount 
from Table t1 
order by cod
into :vCod, :vTime, vcount
do
begin
  if (ocod is NULL) 
  then
  begin
    oCod = vCod; 
    otime = vtime;
    ocount = vcount;
  end
  else
  begin
    if (oCod = vCod)
    then
    begin
    if (otime < vtime)
    then 
    begin 
      otime = vtime;
      ocount = vcount;
    end
end
else
begin
    suspend;
    oCod = vCod; 
    otime = vtime;
    ocount = vcount;
end  
  end
end
    if (oCod = vCod)
    then
begin
if (otime < vtime)
then begin 
    otime = vtime;
    ocount = vcount;
    suspend;
К концу рабочего дня мой мозг родил фоксподобное однопроходное решение, o... - выходные параметры, v... - переменные. Глючить наверно по черному будет, ибо не проверено, совсем... :)

Добавлено: 25 апр 2006, 17:46
hvlad
Senya писал(а):Предлоенный запрос
Ivan_Pisarevsky писал(а):

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

Select t1.Cod, 
  max(t1.fTime), 
  (select fcount 
   from table t2 
   where t1.cod = t2.cod and t2.ftime = max(t1.ftime)) as fcount
from Table t1 
Group by t1.Cod 
Order by 2 
Представляет обычное внутреннее обьеденение и даже при не очень большой таблице N = 5000 записей делает N^2 вычислений а с учетом того что во внутреннем запросе max(t1.ftime) будет пересчитываться каждый раз - так что даже N^3. Я подождал пол часа но ответа на запрос так и не получил.
Это не внутреннее и не "обьеденение".
Индексы создавать пробовал ?