Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Помогите построить запрос / 5 сообщений из 5, страница 1 из 1
07.05.2004, 12:39
    #32510527
PaulJB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите построить запрос
Есть таблица с тремя полями:
- Dt - Счет дебет (Char)
- Kt - Счет кредит (Char)
- nSumma - Сумма
кол-во записей около 300 000

Надо посчитать сумму по каждому счету исключив например 301, 682 и 586, т.е. в итоге получить таблицу:
============
СЧЕТ : СУММА
============

Хотелось бы одним запросом и без использования <>, NOT, NOT IN (...)
На сколько я знаю - они отключают оптимизатор.

ASA 8.0.2.4398
...
Рейтинг: 0 / 0
07.05.2004, 12:42
    #32510541
Александр Спелицин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите построить запрос
Можно сделать двумя запросами: Первый - сумма по всем счетам, второй - сумма по "ненужным" счетам и из первого вычесть второе.
...
Рейтинг: 0 / 0
07.05.2004, 13:18
    #32510610
PaulJB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите построить запрос
2 Александр Спелицин
Мне надо не итоговую сумму по всем счетам, а по каждому счету в отдельности.
...
Рейтинг: 0 / 0
07.05.2004, 13:27
    #32510629
ASCRUS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите построить запрос
Если есть табличка "Справочник счетов", то можно попробовать вот так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
SELECT Id, Sum(Value) AS TotalValue
FROM (
  SELECT s.Id, Sum(o.nSumma) AS Value
  FROM "Операции" o
    INNER JOIN "Счета" s ON s.Id = o.Dt AND s.Id NOT IN ( 301 ,  682 ,  586 )
  GROUP BY s.Id
  UNION ALL
  SELECT s.Id, Sum(-o.nSumma) AS Value
  FROM "Операции" o
    INNER JOIN "Счета" s ON s.Id = o.Kt AND s.Id NOT IN ( 301 ,  682 ,  586 )
  GROUP BY s.Id
) AS x
GROUP BY Id
Получается, что мы TableScan уводим на справочник счетов, а там записей явно не 300 000. Далее результат с таблицы Счета соединяется по индексам с таблицей Операции для дебета и для кредита. При суммировании результатов Дебета и Кредита по идее применяется алгоритм аггрегации по индексу Dt или Kt, который и так уже используется. Далее получаем уже не большое кол-во записей, т.е. примерно получится (Кол_ВоЗаписейВСчетах - Кол_воНенужныхСчетов) * 2 (это если примерно поровну дебетовых и кредитовых операций по счетам). Так как записей не много, то все это уже прекрасно и быстро суммируется без необходимости использовать индексы, т.е. по идее будет применен HASH алгоритм для группировки по номеру счета.

Если таблицы справочника счетов нет, то наверное стоит перед этим запросом организовать ее как временную:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
DECLARE LOCAL TEMPORARY TABLE "Счета" (
  Id char( 10 ) PRIMARY KEY
) NOT TRANSACTIONAL;

INSERT INTO "Счета" (Id)
  SELECT DISTINCT Dt
  FROM "Операции"
  UNION
  SELECT DISTINCT Kt
  FROM "Операции";

DELETE FROM "Счета"
WHERE Id IN ( 301 ,  682 ,  586 );
Дальше по запросу получения остатков, только убрать оттуда условие
s.Id NOT IN (301, 682, 586)

P.S. Это только моя точка зрения, оптимизатор у ASA не только в каждой версии, но и в каждом EBF может по разному придумывать планы запросов, так что не факт, что мой запрос самый удачный. Можно сказать что мной предложен вариант из личного опыта построения примерно таких же запросов на ASA 9 - 9.01 Но можно попробовать в эту сторону покопать.
...
Рейтинг: 0 / 0
07.05.2004, 16:24
    #32510961
PaulJB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите построить запрос
Большое спасибо.
Буду копать ...
...
Рейтинг: 0 / 0
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Помогите построить запрос / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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