Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Помогите упростить алгоритм создания выборки из нескольких таблиц / 7 сообщений из 7, страница 1 из 1
26.05.2005, 22:53:46
    #33086337
Whitish Smoke
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите упростить алгоритм создания выборки из нескольких таблиц
Здравствуйте всем!

Значит, есть такая вещь. Есть 3 таблицы. Первая содержит некие данные об объектах, вторая отражает движение этих обьектов (содержит номера накладных и количество обьектов), а третья является справочником.

Надо сделать выборку.
Она состоит из 3 частей:

1. Данные из первой таблицы, причём часть полей в этой таблице пустует

2. Данные из третьей таблицы (заполняются как раз те поля, что пустые в первой)

3. Данные из второй таблицы, сами данные -- это просто суммы, но вот условия для суммирования кошмарные, уложиться в один запрос не удаётся.

Логика такая.

1. Достаём все доступные данные из 1 таблицы.

Код: plaintext
select fields from table1 where expression и так далее... into array gaItem

2. далее в цикле проходимся по массиву gaItem и вставляем в пустые поля соответствующие значения из справочника.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
for i= 1  to ALEN(gaItem, 1 )
     if EMPTY(gaItem(i,n))
           здесь создаём курсор и помещаем в него выборку -  1  значение.
           и кладём его в ячейку массива
     endif

     и таких if ..... endif  3  штуки
endfor

3. увеличиваем размер (количество столбцов) массива

Код: plaintext
DIMENSION + AINS

4. в цикле вытаскиваем данные из второй таблицы (суммы по условиям) и вставляем в массив

Код: plaintext
в целом похоже на п. 2 .

5. сбрасываем массив в таблицу.

Код: plaintext
ну здесь всё понятно.

6. таблицу выводим в гриде.

Код: plaintext
и здесь тоже

Вот примерно так.

Вопрос, собственно, в следующем: можно это всё дело как то упростить?
Хотя бы общие рекомендации. А то уж больно много селектов получается. И работает это всё не так быстро как хотелось бы.

(больно не бейте, я ещё только учусь)
...
Рейтинг: 0 / 0
26.05.2005, 23:40:16
    #33086357
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите упростить алгоритм создания выборки из нескольких таблиц
Общие рекомендации. Особо не вникал в задачу.

Результатом всех манипуляций должна стать временная таблица. Иначе просто невозможно отобразить полученный результат в Grid. Значит, вполне логично сразу и создать эту временную таблицу (курсор).

Либо напрямую командой CREATE CURSOR, либо (если возможно) запросом из первой таблицы

Код: plaintext
1.
2.
3.
SELECT fields,  000000 . 00  as sum1,  000000 . 00  as sum2 ;
FROM table1
INTO CURSOR tmpCur NOFILTER READWRITE
WHERE ...

здесь поля sum1, sum2 - это те суммы, которые будут заполнены позднее.

Далее запускаешь сканирование курсора или первой таблицы (смотря как ты создал временную таблицу)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
*либо, если курсор создан через CREATE CURSOR
select table1
SCAN FOR ...
...
INSERT INTO tmpCur (...) VALUES (...)
ENDSCAN

* либо, если курсор создан через Select-SQL
select tmpCur
SCAN
...
REPLACE ... WITH ...
ENDSCAN

Ну, информацию из справочника можно подтянуть сразу в запросе.

Менять количество столбцов в массиве - очень неблагодарное занятие
...
Рейтинг: 0 / 0
26.05.2005, 23:51:38
    #33086369
Whitish Smoke
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите упростить алгоритм создания выборки из нескольких таблиц
>Менять количество столбцов в массиве - очень неблагодарное занятие

Совершенно точно. Помучавшись с AINS, я потом плюнул на это дело, и просто продублировал одно из полей таблиц нужное количество раз, хотя это и не красиво.

Ваш вариант -- в принципе то же самое, но более элегантно.

А про скан я и забыл. А насколько это будет быстрее перебора по циклу? Ведь это почти то же самое?

Но всё равно спасибо за ответ.
...
Рейтинг: 0 / 0
27.05.2005, 00:49:55
    #33086399
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите упростить алгоритм создания выборки из нескольких таблиц
Whitish SmokeА про скан я и забыл. А насколько это будет быстрее перебора по циклу? Ведь это почти то же самое?
На вскидку не скажешь. Эффективность того или иного способа зависит от конкретной задачи.

Возможно, быстрее будет несколько последовательных команд Select-SQL, возможно, SCAN+SEEK (или RELATION), возможно, кобинация того и другого.

Оптимизация (читай - ускорение) кода - это достаточно творческое занятие. Далеко ен всегда можно дать совет "на все случаи жизни".
...
Рейтинг: 0 / 0
27.05.2005, 01:07:32
    #33086405
Urri
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите упростить алгоритм создания выборки из нескольких таблиц
Вообще говоря, можно проверить самому. Взять какую-нибудь немаленькую таблицу и примерно так с ней обойтись:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
t = seconds()
for i =  1  to  10 
  go top && здесь - только ради чистоты эксперимента
  scan
    x = eval(field( 1 )) && это тоже ради чистоты эксперимента,
* а то с индексом, возможно, таблица вообще читаться не будет.
  endscan
endfor
?seconds()-t
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
t = seconds()
for i =  1  to  10 
  go top && а здесь без этого никак
  do while !eof()
    x = eval(field( 1 ))
    skip
  enddo
endfor
?seconds()-t
Сначала без активного индекса, потом с установленным по SET ORDER TO ... каким-нибудь индексом повторить. Попробовать в режимах SET DELETED ON и OFF. Записи, конечно, некоторые должны быть удалены. Еще чем-нибудь поиграть.
Результаты можно бросить сюда.
...
Рейтинг: 0 / 0
27.05.2005, 01:13:58
    #33086408
Igor Korolyov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите упростить алгоритм создания выборки из нескольких таблиц
Hi Whitish Smoke!

1) Объединить таблицу1 и справочник(и) можно в одном запросе (это будет более оптимально чем потом городить реляции, сканы, реплейсы и т.п.) - просто вместо имени поля используй выражение - IIF(EMPTY(table1.field1), sprav1.field1, table1.field1) as field1 - ну идея думаю ясна. в более новых версиях фокса это-же делается через EVL(). Если под "пусто" понимается NULL - то соответственно функция NVL()
2) Если подсчёт суммы нельзя оформить простым набором элементарных функций (например типа SUM(IIF(table2.nvalue1=1, table2.nvalue2, table2.nvalue3*table2.nvalue4)-table2.nvalue5))
тогда есть 2 варианта:
- нарисовать свою функцию (UDF) в которой и реализовать логику суммирования (или ещё каких-то расчётов) но считать всё только по одному элементу! Его код (table1.nPK) и передавать в эту функцию - это конечно не супер-быстрое решение, но вполне работоспособное.
- сделать в первом запросе "заглушки" вида 00000.00 as nSum1 и заполнить потом всё через цикл SCAN.

Posted via ActualForum NNTP Server 1.2
...
Рейтинг: 0 / 0
27.05.2005, 01:45:52
    #33086421
Whitish Smoke
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите упростить алгоритм создания выборки из нескольких таблиц
>Результаты можно бросить сюда.

Уже интересно. Постараюсь.


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


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