Страница 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. Я подождал пол часа но ответа на запрос так и не получил.
Это не внутреннее и не "обьеденение".
Индексы создавать пробовал ?