Текущий архив: 2003.05.22;
Скачать: CL | DM;
Вниз
SQL - нарастающий итог Найти похожие ветки
← →
Silver_ (2003-04-25 16:40) [0]fld1 fld2 Calc_fld3
1 5 5
2 2 7
13 10 17
4 11 28
35 1 29
SELECT * SUM(fld1 до текущей записи) AS Calc_fld3
FROM Table1
← →
Silver_ (2003-04-25 17:30) [1]ладно пойдем по другому пути
КАК узнать номер текущей записи типа RecNo
забыл СУБД Access
← →
Silver_ (2003-04-25 18:42) [2]Не ребята не поверю что энто никому не нужно
хоть идеи какие-нить есть??? тожа не лишним будет!!!
← →
NickBat (2003-04-25 18:49) [3]Хочешь верь - хочешь не верь.
Нарастающий итог, как правило, необходим при выводе отчета на печать, как итог по отдельным группам. Это делается генераторами отчетов.
Номер записи не играет в реляционнных БД никакого значения, а если ты сортируешь их по какому-то признаку, то должен знать на какой записи тебе необходимо закрнчить подсчет, вот и ограничь условием where field<n
← →
Silver_ (2003-04-25 19:02) [4]дело в том что результаты нужны для последубщей обработки
← →
NickBat (2003-04-25 19:09) [5]обработки кем? чем?
← →
sniknik (2003-04-25 23:34) [6]Silver_ © (25.04.03 17:30)
> КАК узнать номер текущей записи типа RecNo
не повериш но значение RecNo можно узнать через ADODataSet1.RecNo хотя в большинстве случаев этот номер смысла не имеет, и иногда (от настроек) равен -1 для всех записей.
(лутще пересмотри алгоритм, не закладываясь на RecNo)
← →
Silver_ (2003-04-29 09:54) [7]
> Silver_ © (25.04.03 17:30)
> > КАК узнать номер текущей записи типа RecNo
← →
Silver_ (2003-04-29 09:57) [8]
> Silver_ © (25.04.03 17:30)
> > КАК узнать номер текущей записи типа RecNo
имел ввиду через SQL
P.S. Извиняюсь за предыдущее послание (празники, просыпаться не хочется блин :) )
← →
Соловьев (2003-04-29 09:57) [9]
> > Silver_ © (25.04.03 17:30)
> > > КАК узнать номер текущей записи типа RecNo
тебе же написал NickBat © (25.04.03 18:49), что все зависит от сортировки. Нет такого понятия как номер записи. Это иллюзия.
← →
GLUKAS (2003-04-29 09:58) [10]Можно его сгенирировать если есть уникальный ключ....
И только при сортировке по нему!
Так: Select id,f1,f2,f3,...,(select count(*) from table1 where id<t1.id) from Table1 t1;
← →
sniknik (2003-04-29 10:46) [11]Соловьев © (29.04.03 09:57)
> Нет такого понятия как номер записи. Это иллюзия.
ну не нужно из крайности в крайность, только изза того что он бессмысленен (в большинстве случаев, уже говорил), и SQL почти всех баз его не поддерживают. Есть исключения.
и тогда работает (раз драйвер базы поддерживает номер)
SELECT *, RecNo() AS RecordNum FROM Table
убедится что это именно номер записи можно сделав сортировку
SELECT *, RecNo() AS RecordNum FROM Table ORDER BY Field
номера пойдут не по порядку.
но это только если драйвер/sql сервер поддерживает. надо смотреть конкретно в документацию. эти 2 примера будут работать только с -
Provider=MSDASQL.1;Persist Security Info=False;Extended Properties="DRIVER={Microsoft Visual FoxPro Driver};UID=;SourceDB=d:\;SourceType=DBF;Exclusive=No;BackgroundFetch=Yes;Collate=RUSSIAN;Null=Yes;Deleted=Yes;"
для Access такого нет, во всяком случае я не знаю.
GLUKAS © (29.04.03 09:58)
ну это же будет не совсем то, правильно? если например нужно сделать order by по какому нибудь полю, номера для полей покажет другие.
может лутше сделать автоикремент? и все? лутше конечно менять логику.
← →
Silver_ (2003-04-29 10:58) [12]Выкладываю РАБОТАЮЩИЙ код
SELECT MIN(A.Fld1)as f1, MIN(A.Fld2) AS f2, SUM(B.Fld2) AS SUM_f2
FROM Table1 A INNER JOIN Table1 B ON A.Fld1 >= B.Fld1
GROUP BY A.Fld1
P.S. Думаю вопрос закрыт, за исключением представления более лудшего варианта :)
← →
sniknik (2003-04-29 11:25) [13]> за исключением представления более лудшего варианта
а ошибки этого обсудить?
Fld1-это автоикремент? а если он с "разрывами" что будет?
GLUKAS © (29.04.03 09:58)
дал лутший вариант (по моему).
← →
Sergey13 (2003-04-29 11:34) [14]Что-то я ни в одном варианте запросов не увидел WHERE. Если надо постоянно по всей таблице иметь этот итог, то может проще поле добавить? Если же все таки надо по произвольной выборке, то я для таких штук использовал таблицы в памяти RxMemoryData. Загонял туда датасет (или его часть), добавлял поле и в цикле считал этот итог. ИМХО, это выгоднее получится, чем в запросе.
← →
Silver_ (2003-04-29 11:40) [15]
> Fld1-это автоикремент?
ДА.
SELECT MIN(A. ID )as f1, MIN(A.Fld2) AS f2, SUM(B.Fld2) AS SUM_f2
FROM Table1 A INNER JOIN Table1 B ON A. ID >= B. ID
GROUP BY A. ID
так понятней будет
> а если он с "разрывами" что будет?
все прекрасно работает и с "разрывами" тоже, Проверено лично мной на конкретном примере.
← →
Silver_ (2003-04-29 11:48) [16]
> 2 Sergey13 © (29.04.03 11:34)
> Что-то я ни в одном варианте запросов не увидел WHERE
...и не нужен. Происходит следующее для каждой записи в подчинении находятся все предыдущие, их сумма (получаемая по GROUP BY A.ID) и получается искомое значение
> добавлял поле и в цикле считал этот итог
не знаю как "таблицы в памяти RxMemoryData" но в цикле так тормозит что... а SQL хоть и не моментально (данных много) но терпимо.
← →
Dnico (2003-04-29 12:20) [17]Если это на Interbase - то можно при помощи ХП
sumqty = 0;
for select id, qty from "table1" where ....
order by id
into :id, :qty do begin
sumqty = sumqty + :qty;
suspend;
end
← →
sniknik (2003-04-29 12:38) [18]Silver_ © (29.04.03 11:40)
тоже пробовал в "реале"
SELECT MIN(A.ID) as RecNo, MIN(A.ID) AS f2, SUM(B.ID) AS SUM_f2
FROM Data_OUT A INNER JOIN Data_OUT B ON A.ID >= B.ID
GROUP BY A.ID
RecNo я правильно поставил?
значения ID 1,2,3,9
получившиеся значения RecNo 1,2,3,9
и ли я не там смотрю?
← →
Sergey13 (2003-04-30 08:48) [19]2Silver_ © (29.04.03 11:48)
> Происходит следующее для каждой записи в подчинении находятся все предыдущие, их сумма (получаемая по GROUP BY A.ID) и получается искомое значение
Если на таблице отсутствует update/delete то ИМХО лучше добавить поле и писать итог туда
>не знаю как "таблицы в памяти RxMemoryData" но в цикле так тормозит что... а SQL хоть и не моментально (данных много) но терпимо.
А сколько много? У тебя возможно тормозит выкачивание "данных много", а не обход циклом по ним.
← →
Silver_ (2003-04-30 10:46) [20]
> Если на таблице отсутствует update/delete то ИМХО лучше
> добавить поле и писать итог туда
Вся беда в том что есть требуется предвидеть ситуацию/возможность ввода/корректировки данных задним числом (забыли ввести некие данные или на момент ввода небыло известно онеких изменениях...). Если итог напрямую туда написать получим неверные вычисления...
> У тебя возможно тормозит выкачивание "данных много", а не
> обход циклом по ним.
с RxMemoryData вопще не работал и даже принципа его работы не знаю
сравни
ADODataSet1.CommandText:="SELECT * FROM Table1"
ADODataSet1.Open;
Total:=0;
//----- сравни скорость начиная здесь
while not ADODataSet.Eof do
Total:=Total + ADODataSet.FieldByName("Num_Value").AsInteger;
//----- сравни скорость заканчивая здесь
ADODataSet1.CommandText:="SELECT * SUM(Num_Value) AS Total FROM Table1"
//----- сравни скорость начиная здесь
ADODataSet1.Open;
//----- сравни скорость заканчивая здесь
← →
Sergey13 (2003-04-30 11:16) [21]2Silver_ © (30.04.03 10:46)
>Вся беда в том что есть требуется предвидеть ситуацию/возможность ввода/корректировки данных задним числом (забыли ввести некие данные или на момент ввода небыло известно онеких изменениях...).
Если такая ситуация только возможна, но не очевидна, то ИМХО, можно сделать процедуру пересчета по всей таблице и вызывать ее после ввода/исправления всех данных.
>с RxMemoryData вопще не работал и даже принципа его работы не знаю
Обычная таблица, но не в базе а в памяти.
>сравни...
А что у тебя за запрос? Если он вообще отработает (сомневаюсь) то ты просто получишь сумму по столбцу, без всякого нарастающего итога. Ты его наверное "творчески переработал" для публикации на форуме.
"Ускорение" в твоем случае скорее всего происходит из за того, что при Open ты еще не получил всех записей. Добавь строчку ADODataSet1.Last (я с ADO не работал, но наверное там есть такой метод) и меряй после нее.
При вычислении SUM в запросе происходит многократное (на каждую запись) выполнение этого агрегата для всех предыдущих записей. А при обходе циклом все делается за один проход.
Кстати, может попробовать добавить вычисляемое поле, значение которого будет считаться как select sum(Num_value) from table where id<:id. Но в твоем случае (ИМХО) все таки лучше наверное нормальное поле.
← →
Sergey13 (2003-04-30 11:28) [22]22Silver_ © (30.04.03 10:46)
В догонку.
А зачем тебе вся таблица на клиенте? Может надо то только за последний месяц (неделю, день). Ограничь выборку. Посчитай одним запросом сумму "до начала выборки", а дальше как я предлагал. Вообще летать все будет.
← →
Silver_ (2003-04-30 12:09) [23]
> Обычная таблица, но не в базе а в памяти.
это я понял (даже смею предположить Metods, Events те же/похожие)
> А что у тебя за запрос? Если он вообще отработает (сомневаюсь)
> то ты просто получишь сумму по столбцу, без всякого нарастающего
> итога. Ты его наверное "творчески переработал" для публикации
> на форуме.
Само сабой
> Silver_ © (25.04.03 19:02)
> дело в том что результаты нужны для последубщей обработки
...тоже желательно через SQL
так как спрашивал про нарастающий итог выложил рабочий пример упрощенный для более легкого понимания
> При вычислении SUM в запросе происходит многократное (на
> каждую запись) выполнение этого агрегата для всех предыдущих
> записей.
согласен но это происходот быстрее цикла даже по всей таблице (нельзя исключать и такой ситуации)
> Ограничь выборку.
обязательно условие WHERE для этого имеется/использую
P.S. В конце концов частичные вычисления все равно придется делать прходом уж больно много вычислений и исключений и...
но что возможно буду через SQL делать уже убедился Хорошая/быстрая вещч (раньше кстати недолюбливал/не пользовал)
← →
Silver_ (2003-04-30 12:49) [24]
> sniknik © (29.04.03 12:38)
> Silver_ © (29.04.03 11:40)
> тоже пробовал в "реале"
> SELECT MIN(A.ID) as RecNo, MIN(A.ID) AS f2, SUM(B.ID) AS
> SUM_f2
> FROM Data_OUT A INNER JOIN Data_OUT B ON A.ID >= B.ID
> GROUP BY A.ID
>
> RecNo я правильно поставил?
>
> значения ID 1,2,3,9
> получившиеся значения RecNo 1,2,3,9
> и ли я не там смотрю?
не там
интересует SUM_f2 (f2=10,20,30,90 => SUM_f2= 10,30,60,150)
> Dnico (29.04.03 12:20)
Но у меня кстати Access тут мона ХП раньше пользовал SyBase там понятно в базе и делаеш а в Access??
Страницы: 1 вся ветка
Текущий архив: 2003.05.22;
Скачать: CL | DM;
Память: 0.51 MB
Время: 0.007 c