powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Пересчет построчно таблицы.
25 сообщений из 30, страница 1 из 2
Пересчет построчно таблицы.
    #38731227
Stind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет!

Вопрос такой. Есть табличка. Столбцов - 70, строк -1500.
Требуется значения столбцов второй строки пересчитать как сумму имеющегося значения + значение столбца первой строки.
Соответственно, для третьей строки - сумма значений уже новой второй + значение третьей.

Алгоритм элементарный, но... На табличку уходит 0.5 сек., а табличек .... - 60.000. Итого - 8 часов.
Может, есть что-то поумнее простого перебора строк?
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38731258
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если алгоритм это скан таблицы в один проход, то улучшать его бесполезно.

Можно добавить для ускорения следующее:
1. Открытие файлов монопольно (быстрее чтение запись)
2. Надеюсь файлы локально лежат (не по сети качаются)
3. Распараллелить обработку, т.е. запустить несколько копий обработчиков и каждому дать свою группу файлов. Сколько копий оптимально не скажу, как минимум сколько ядер у процессора, точнее можно опытным путем затестить.
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38731285
Stind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T,

0. Не сканом... Считывается в массив первая строка, вторая. Второй присваивается значение суммы двух, запоминается в массив.
считывается третья - складывается с массивом второй и запоминается.. И тд.

1. монопольно
2. локально
3. подумаю, но, кажется проблема в п.0
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38731340
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stind0. Не сканом... Считывается в массив первая строка, вторая. Второй присваивается значение суммы двух, запоминается в массив.
считывается третья - складывается с массивом второй и запоминается.. И тд.
...
3. подумаю, но, кажется проблема в п.0

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE CURSOR test (f1 int, f2 int, f3 int)

INSERT INTO test VALUES (1,1,1)
INSERT INTO test VALUES (2,3,4)

UPDATE test SET f3 = f3 + (f2 + f1), f2 = f2 + f1

BROWSE 
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38731443
Stind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PaulWist,

Не совсем такая задача...
Требуется складывать значения строк по столбцам.


имеем

1 1 1
2 3 4
3 2 1

Должно получится

1 1 1
3 4 5
6 6 6
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38731514
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
StindPaulWist,

Не совсем такая задача...
Требуется складывать значения строк по столбцам.


имеем

1 1 1
2 3 4
3 2 1

Должно получится

1 1 1
3 4 5
6 6 6

1. По какому признаку определяется, где первая "строка", где вторая?

2. Надо получить в конце концов - нарастающий итог?

3. Первичный ключ у табличек есть?
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38731522
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На держи, только в таблички нужно добавить нарастающий первичный ключ определяющий порядок "строк" (если его нет).

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
CREATE CURSOR test (id int AUTOINC, f1 int, f2 int, f3 int)

INSERT INTO test (f1, f2, f3) VALUES (1,1,1)
INSERT INTO test (f1, f2, f3) VALUES (2,3,4)
INSERT INTO test (f1, f2, f3) VALUES (3,2,1)

UPDATE test SET ;
f1 = xx.f1, ;
f2 = xx.f2, ;
f3 = xx.f3 ;
from ;
( ;
SELECT ;
f1 as id, ;
(SELECT SUM(f1) FROM test t1 WHERE t1.id <= t.id ) as f1, ;
(SELECT SUM(f2) FROM test t1 WHERE t1.id <= t.id ) as f2, ;
(SELECT SUM(f3) FROM test t1 WHERE t1.id <= t.id ) as f3 ;
FROM test t ORDER BY f1 ;
) xx ;
inner join test on test.f1 = xx.id

BROWSE FIELDS f1, f2, f3
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38731526
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так будет правильней

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
CREATE CURSOR test (id int AUTOINC, f1 int, f2 int, f3 int)

INSERT INTO test (f1, f2, f3) VALUES (1,1,1)
INSERT INTO test (f1, f2, f3) VALUES (2,3,4)
INSERT INTO test (f1, f2, f3) VALUES (3,2,1)

UPDATE test SET ;
f1 = xx.f1, ;
f2 = xx.f2, ;
f3 = xx.f3 ;
from ;
( ;
SELECT ;
ID, ;
(SELECT SUM(f1) FROM test t1 WHERE t1.id <= t.id ) as f1, ;
(SELECT SUM(f2) FROM test t1 WHERE t1.id <= t.id ) as f2, ;
(SELECT SUM(f3) FROM test t1 WHERE t1.id <= t.id ) as f3 ;
FROM test t ORDER BY f1 ;
) xx ;
inner join test on test.f1 = xx.id

BROWSE FIELDS f1, f2, f3
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38731533
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А так ещё лучше (думаю идея понятна):

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
CREATE CURSOR test (id int AUTOINC, f1 int, f2 int, f3 int)

INSERT INTO test (f1, f2, f3) VALUES (1,1,1)
INSERT INTO test (f1, f2, f3) VALUES (2,3,4)
INSERT INTO test (f1, f2, f3) VALUES (3,2,1)

UPDATE test SET ;
f1 = xx.f1, ;
f2 = xx.f2, ;
f3 = xx.f3 ;
from ;
( ;
SELECT ;
ID, ;
(SELECT SUM(f1) FROM test t1 WHERE t1.id <= t.id ) as f1, ;
(SELECT SUM(f2) FROM test t1 WHERE t1.id <= t.id ) as f2, ;
(SELECT SUM(f3) FROM test t1 WHERE t1.id <= t.id ) as f3 ;
FROM test t ORDER BY ID ;
) xx ;
inner join test on test.f1 = xx.id

BROWSE FIELDS f1, f2, f3
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38731597
Stind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PaulWistStindPaulWist,

Не совсем такая задача...
Требуется складывать значения строк по столбцам.


имеем

1 1 1
2 3 4
3 2 1

Должно получится

1 1 1
3 4 5
6 6 6

1. По какому признаку определяется, где первая "строка", где вторая?

2. Надо получить в конце концов - нарастающий итог?

3. Первичный ключ у табличек есть?




1. Первая строка - это первая строка (без индексов).... последняя - последняя.
2. Требуется для каждой строки (со второй) иметь текущий нарастающий итог.
3. Ключей нет.

Спасибо, покопаюсь...
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38731661
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stind1. Первая строка - это первая строка (без индексов).... последняя - последняя.
2. Требуется для каждой строки (со второй) иметь текущий нарастающий итог.
3. Ключей нет.

Спасибо, покопаюсь...

1. То есть, если последнюю строку сделать первой, то совершенно не важно, что "нарастающий итог" в со второй по предпоследнюю строчку поменяется, ... мдя.

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

3. Опа, а как ты отличаешь одну запись от другой?
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38731676
Stindпропущено...
1. Первая строка - это первая строка (без индексов).... последняя - последняя.
2. Требуется для каждой строки (со второй) иметь текущий нарастающий итог.
3. Ключей нет.

Так только для ограниченного круга задач (когда таблицы полностью помещаются в памяти и только дописываются) можно делать. Иначе - проблем не оберешься.
Например: некто пометил на удаление строку в таблице и физически третья строка логически стала второй. Это что же, все нижеследующие строки пересчитывать? А если их не одна, а миллион?

Проверьте алгоритм, скорее всего ошибка именно в нем... и Вашу задачу можно решить намного проще...
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38731691
PaulWistStind1. Первая строка - это первая строка (без индексов).... последняя - последняя.
2. Требуется для каждой строки (со второй) иметь текущий нарастающий итог.
3. Ключей нет.

Спасибо, покопаюсь...

1. То есть, если последнюю строку сделать первой, то совершенно не важно, что "нарастающий итог" в со второй по предпоследнюю строчку поменяется, ... мдя.

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

3. Опа, а как ты отличаешь одну запись от другой?

Я так думаю, что таблички каждый раз формируются заново какой-то процедурой, являющейся для ТС "черным ящиком"... И единственный ключ, что ему доступен - порядок записей...
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38731692
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
StindТребуется складывать значения строк по столбцам.

имеем
1 1 1
2 3 4
3 2 1

Должно получится
1 1 1
3 4 5
6 6 6
Так подойдет?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
create cursor t (f1 i, f2 i, f3 i)
insert into t (f1, f2, f3) values (1, 1, 1)
insert into t (f1, f2, f3) values (2, 3, 4)
insert into t (f1, f2, f3) values (3, 2, 1)

* Рассчет
sele t
go top
sf1 = t.f1
sf2 = t.f2
sf3 = t.f3
skip
scan while .T.
	sf1 = sf1 + t.f1
	sf2 = sf2 + t.f2
	sf3 = sf3 + t.f3
	repl in t f1 with sf1, f2 with sf2, t.f3 with sf3
endscan
brow
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38731700
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По-хорошему надо создавать новую таблицу с результатом и писать в нее, т.к. писать в исходную таблицу не самая хорошая идея, например что-то сглючит и останется таблица наполовину пересчитанная, или наоборот случайно дважды обработаешь.
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38732316
sqlnew
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PaulWist
1. То есть, если последнюю строку сделать первой, то совершенно не важно, что "нарастающий итог" в со второй по предпоследнюю строчку поменяется, ... мдя.

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

3. Опа, а как ты отличаешь одну запись от другой?

1. А зачем менять? Таблички стабильны, собственно, первая строка - данные за сегодня, вторая - за вчера, третья - позавчера. Т.о. "обратный" нарастающий итог.

2. Соответственно, порядок всегда один.

3. По номеру записи.

Кстати, в первом столбце прописывается дата, но, естественно, в итогах не расчитывается
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38732318
sqlnew
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Станислав С...кийЯ так думаю, что таблички каждый раз формируются заново какой-то процедурой, являющейся для ТС "черным ящиком"... И единственный ключ, что ему доступен - порядок записей...

Нет, таблички я сам формирую. Ключа нет, просто иду по записям сверху вниз.
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38732319
sqlnew
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Станислав С...кийТак только для ограниченного круга задач (когда таблицы полностью помещаются в памяти и только дописываются) можно делать. Иначе - проблем не оберешься.
Например: некто пометил на удаление строку в таблице и физически третья строка логически стала второй. Это что же, все нижеследующие строки пересчитывать? А если их не одна, а миллион?

Проверьте алгоритм, скорее всего ошибка именно в нем... и Вашу задачу можно решить намного проще...

Никто с этими табличками не работает. Данные в них никак не меняются (кроме обратного счета).
И, кстати, неплохая мысль - м.б. грузить таблицу в 2-мерный массив и работать в памяти, а потом выгружать в файл?
Много времени ведь тратится на чтение-запись диска...
Есть функция загрузки таблицы в массив и обратно?
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38732323
sqlnew
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПо-хорошему надо создавать новую таблицу с результатом и писать в нее, т.к. писать в исходную таблицу не самая хорошая идея, например что-то сглючит и останется таблица наполовину пересчитанная, или наоборот случайно дважды обработаешь.

Согласен, но эта запись-перезапись опять съест время, а сбоить вроде негде...
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38732324
sqlnew
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Ок, спасибо за текст. Попробую...
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38732329
sqlnew
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Вдогонку. В принципе, у меня сделано аналогично... Проблема в том, что имена столбцов, их количество и их порядок каждый день могут измениться (выгрузка работает ночью раз в сутки).
Поэтому впрямую такой алгоритм даже не знаю, как и применить...
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38732353
Stind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Во блин, и реинкарнация... Ник-то туевую тучу лет как спал!
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38732381
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sqlnewИ, кстати, неплохая мысль - м.б. грузить таблицу в 2-мерный массив и работать в памяти, а потом выгружать в файл?
Много времени ведь тратится на чтение-запись диска...
В массив целиком твоя таблица просто не влезет, т.к. возможно максимум 65000 переменных, т.е. массив не более 65000 элементов. По умолчанию ~16000.

sqlnewПроблема в том, что имена столбцов, их количество и их порядок каждый день могут измениться
Так все-таки "могут" или "меняются" ? Если "могут измениться" это просто попытка решить задачу раз и навсегда с учетом будущих изменений стуктуры, то лучше на эту тему не заморачиваться, т.к. при твоем объеме важна скорость, а любая попытка написать что-то универсальное только создаст лишние тормоза. Проще добавить проверку структуры при открытии и в случае несовпадения писать в лог или еще как-то сигнализировать.

Если используешь макроподстановки или EVAL() - это тормоза.

Попробуй SCATTER/GATHER
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
create cursor t (dt d, f1 i, f2 i, f3 i)
insert into t (dt, f1, f2, f3) values (date(), 1, 1, 1)
insert into t (dt, f1, f2, f3) values (date()+1, 2, 3, 4)
insert into t (dt, f1, f2, f3) values (date()+2, 3, 2, 1)

sele t
* Построение списка суммируемых полей (допили под свои правила)
scatter to sumlist 
fieldcount = alen(sumlist)
for i = 1 to fieldcount
	if vartype(sumlist[i]) = 'N'
		sumlist[i] = .T.
	else
		sumlist[i] = .F.
	endif
endfor

* Расчет
go top
scatter to sf 
skip
scan while .T.
	scatter to sf2
	for i = 1 to fieldcount
		if sumlist[i]
			sf[i] = sf[i] + sf2[i]
		endif
	endfor
	gather from sf
endscan
brow



sqlnewпервая строка - данные за сегодня, вторая - за вчера, третья - позавчера. Т.о. "обратный" нарастающий итог.
...
Нет, таблички я сам формирую.
Я так подозреваю что перед этим ночным расчетом генерация этих табличек происходит. Может есть смыл совместить?
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38733597
sqlnew
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T1. В массив целиком твоя таблица просто не влезет, т.к. возможно максимум 65000 переменных, т.е. массив не более 65000 элементов. По умолчанию ~16000.

2. Так все-таки "могут" или "меняются" ? Если "могут измениться" это просто попытка решить задачу раз и навсегда с учетом будущих изменений стуктуры, то лучше на эту тему не заморачиваться, т.к. при твоем объеме важна скорость, а любая попытка написать что-то универсальное только создаст лишние тормоза. Проще добавить проверку структуры при открытии и в случае несовпадения писать в лог или еще как-то сигнализировать.

3. Если используешь макроподстановки или EVAL() - это тормоза.

4. [spoiler Попробуй SCATTER/GATHER]

5. Я так подозреваю что перед этим ночным расчетом генерация этих табличек происходит. Может есть смыл совместить?



1.
declare xx_p[1500*100]
xx_p=0
xx_p[1500*100]=1
? xx_p[1500*100]
1!
Или где-то засада?

2. Ну, может. Реально столбцы могут меняться редко.

3. Макры есть ;-(

4. Попробую... Спасибо.

5. Пробовал, тогда тормоза добавляются к тому расчету...
...
Рейтинг: 0 / 0
Пересчет построчно таблицы.
    #38734296
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sqlnew1.
declare xx_p[1500*100]
xx_p=0
xx_p[1500*100]=1
? xx_p[1500*100]
1!
Или где-то засада?
Действительно работает, похоже попатчили в 9ке эту проблему, в 6-ке у меня были проблемы с adir() на папках с несколькими десятками тысяч файлов. Выпадывало по ошибке "Too many variables"

sqlnew3. Макры есть ;-(
Избавляйся

sqlnew5. Пробовал, тогда тормоза добавляются к тому расчету...
Я бы их параллельно запускал:
1. Первый процесс генерит в папку А
2. Второй процесс берет по одному файлу с папки А, обсчитывает, перемещает (не копирует) в папку Б. Второй мониторит папку постоянно, если за минуту ни одного файла не появилось - останавливается.
...
Рейтинг: 0 / 0
25 сообщений из 30, страница 1 из 2
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Пересчет построчно таблицы.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]