Delphi + Interbase
2162
7
Тут у знакомого возник один вопрос по delphi + Interbase, я, к сожалению в этом профан, поэтому решил тут спросить.

Допустим, есть две таблицы:

таблица ордеров (Ordera)
I_Ord - код ордера
Dat - дата
VdOr - 'P' - приходный ордер, 'R' - расходный ордер

таблица товаров (Tovars)
I_Tov - код товара
I_Ord - код ордера
Kvo - количество

Одной записи в Ordera может соответствовать несколько в Tovars (связь по I_Ord). Задача получить остаток товара.

Следующий запрос дает список всего товара, причем кол-во товара по приходным ордерам идет со знаком '+', а по расходным ордерам -со знаком '-':

SELECT OD.I_TOV, TV.KVOT
FROM PRORDS OD, PRTOVS TV
WHERE OD.I_OR=TV.I_OR AND OD.VDOR="P"
UNION
SELECT OD.I_TOV, -1*TV.KVOT
FROM PRORDS OD, PRTOVS TV, MATCEN MC
WHERE OD.I_OR=TV.I_OR AND OD.VDOR="R"

Теперь хорошо бы просуммировать эти данные, сгруппировав по коду товара (I_Tov), но как обратиться к результату этого запроса в Delphi?

Должно быть что-то типа:
SELECT I_Tov, SUM(KvoT) AS KvoT
FROM
GROUP BY I_Tov

Может можно получить результат одним SQL-запросом?

Или есть какой-нибудь другой вариант?
Duk
разве не проще сделать ещё один запрос?
В смысле? А где промежуточные значения хранить?
Duk
1. всё же лучше union all, имхо
2. декартово произведение не есть хорошо
3.1 результаты запроса сохраняются в файл, после чего запросом обращаемся к этому файлу.
3.2 мысли вслух: а не проще ли значения хранить со знаками и колонку с признаком убрать
Duk
Не знаю как другие, а я бы не парясь создал просмотр по результату первого запроса и второй запрос делал по просмотру
Дело в том, что это оказалось тествое задание и комментарии по нормализации таблицы не принимаются:улыб:А вообще говоря я ему нашёл такое решение, если кому интересно - Замена временных таблиц в FireBird

По-моему довольно стильно и всё по-честному без всяких дополнительных файлов:улыб:
Duk
Схематично:
я бы добавил таблицу такого вида
CREATE TABLE DocTypes
(
DocTypeID char(1)not null primary key,
Multiplier integer not null
)
и занес туда 2 записи: ('P',1) и ('R',-1)

Тогда запрос легко переписывается к такому виду

SELECT OD.I_TOV, SUM(TV.KVOT*DT.Multiplier)
FROM
PRORDS OD
INNER JOIN PRTOVS TV ON OD.I_OR=TV.I_OR
INNER JOIN DocTypes DT ON OD.VDOR=DT.DocTypeID

без всяких UNION'ов, вьюшек(UNION в них недопустим) и лишних наворотов.

P.S. Не забудьте добавить FK по полю DocTypeID:улыб:

P.P.S. Писать запросы с условием объединения в WHERE, а не на JOIN'ах - очень дурной тон, если это делается не на Оракле.

P.P.P.S. Даже если это тестовое задание, то не улучшить структуру в данном случае- это еще более дурной тон.