Нужна помощь в написании ХП или запрос (ФИФО)
Нужна помощь в написании ХП или запрос (ФИФО)
Здравствуйте уважаемые форумчане.
Что то никак не приходит в голову как оформить следующую процедуру.
Есть таблица покупок и продаж (операции) товаров в которой следующие поля:
ID BIGINT
TYPEOPER SMALLINT (тип операции 1-покупка, 2-продажа)
ITEM INTEGER (номер товара)
VOLUME INTEGER
Необходимо чтобы запрос выводил данные таким обарзом чтобы каждая строка отражала движение товара, т.е. предположим куплено в одной операции 100 ед товара 1, а продавалось 2-мя операциями по 80 и 20, соответственно 2 строки в результирующей таблице. Или наоборот куплено 2-мя операциями 30 и 70 а продано одной 100 ед (опять 2 строки). Ну и самый простой вариант когда куплено 100 и продано 100, тогда одна строк (по методу ФИФО).:
ITEM VOLUME_BUY VOLUME_SELL
Вот что то и не могу придумать как побороть такую задачу.
Благодярен за любую помощь
Что то никак не приходит в голову как оформить следующую процедуру.
Есть таблица покупок и продаж (операции) товаров в которой следующие поля:
ID BIGINT
TYPEOPER SMALLINT (тип операции 1-покупка, 2-продажа)
ITEM INTEGER (номер товара)
VOLUME INTEGER
Необходимо чтобы запрос выводил данные таким обарзом чтобы каждая строка отражала движение товара, т.е. предположим куплено в одной операции 100 ед товара 1, а продавалось 2-мя операциями по 80 и 20, соответственно 2 строки в результирующей таблице. Или наоборот куплено 2-мя операциями 30 и 70 а продано одной 100 ед (опять 2 строки). Ну и самый простой вариант когда куплено 100 и продано 100, тогда одна строк (по методу ФИФО).:
ITEM VOLUME_BUY VOLUME_SELL
Вот что то и не могу придумать как побороть такую задачу.
Благодярен за любую помощь
-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34
Значит исходная таблица OPERATION:Ivan_Pisarevsky писал(а):Набросай с десяток строк в исходной таблице и результат в виде ТАБЛИЦЫ, типа так есть: ... так хочу видеть: ...
ID - индекс
TYPEOPER - тип операции (1-покупка, 2-продажа)
ITEM - номер товара
VOLUME - количество
PRICE - цена (покупки/продажи)
Код: Выделить всё
ID | TYPEOPER | ITEM | VOLUME | PRICE
1 | 1 | 1 | 50 | 20.50
2 | 1 | 1 | 80 | 21.00
3 | 2 | 1 | 100 | 25.20
4 | 1 | 2 | 500 | 12.30
5 | 2 | 2 | 500 | 18.45
6 | 1 | 1 | 30 | 21.20
7 | 2 | 1 | 60 | 25.20
8 | 1 | 3 | 4 | 103.42
9 | 2 | 3 | 2 | 140.00
10 | 2 | 3 | 1 | 141.00
Код: Выделить всё
ID_BUY | ID_SELL | ITEM | VOLUME | PRICE_BUY | PRICE_SELL
1 | 3 | 1 | 50 | 20.50 | 25.20
2 | 3 | 1 | 50 | 21.00 | 25.20
4 | 5 | 2 | 500 | 12.30 | 18.45
2 | 7 | 1 | 30 | 21.00 | 25.20
6 | 7 | 1 | 30 | 21.20 | 25.20
8 | 9 | 3 | 2 | 103.42 | 140.00
8 | 10 | 3 | 1 | 103.42 | 141
Последний раз редактировалось connor74 01 июл 2007, 10:06, всего редактировалось 1 раз.
ну ты бы в тег [ code] выделил, а то ну совсем не понятно.
вот про третью строчку не понятно, она не парная, потому что её не продали ? а у нее кол-во одинаковое.
ну что ХП это уже понятно =) хотя и блоком можно .
может ошибаюсь но должно быть что-то вроде:
вот про третью строчку не понятно, она не парная, потому что её не продали ? а у нее кол-во одинаковое.
ну что ХП это уже понятно =) хотя и блоком можно .
может ошибаюсь но должно быть что-то вроде:
Код: Выделить всё
--переменых паручку
countrecord1 integer;
countrecord2 integer;
--выбираем все что купили
for select *,count(1) from OPERATION
join **
group by *
where TYPEOPER = 1
into ***,countrecord1 --содержит за сколько операций купили
do begin
suspend;
--
select *,count(1) from OPERATION
join **
where TYPEOPER = 2
and ITEM = :ITEM
group by *
into ***, countrecord2 --содержит за сколько операций продали
do if (countrecord1 <> countrecord2) then
suspend; -- отправляем только если кол-во разное ставишь условие нужное тебе
end
-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34
to Attid
Често говоря твой пост не понял, как можно строить фифо без ордер бая по дате операции как-то в голове не очень укладывается...
ИМХО примерно следущее:
переменные
curr_date_oper /*текущая дата продажи*/
curr_oper /*текущая продажа, ключ*/
not_sale /*остаток товара*/
for
select ...
from operation
where <все операции прихода по выбранным товарам за требуемый период>
order by item, date_oper
into <переменные>
do
begin
while not_sale >0
do
begin
/*берем первый расход по данному товару*/
select first 1 ...
from operation
where <расход по выбранному товару за требуемый период при этом берем больше текущей даты и больше текущей опреции расхода, чтоб не зациклится>
order by date_oper, id_oper
into <переменные>;
/*закрываем приход расходом, пока есть ненулевой остаток, как только попытка превысить прокручиваемся на следущую запись в приходе и пошли по новой, попутно продвигаем текущую дату продажи и текущий остаток*/
suspend;
end
end
Алгоритм где-то так, можно вместо while+first сделать for select, в принципе. Как это запихнуть в один запрос пока не представляю.
Если делать на клиенте, я бы сделал два датасэта и прокручивал бы их за один проход параллельно, вот БЫ сделать такой финт в ХП. Хотя мож я просто от жизни поотстал и уже можно...
Често говоря твой пост не понял, как можно строить фифо без ордер бая по дате операции как-то в голове не очень укладывается...
ИМХО примерно следущее:
переменные
curr_date_oper /*текущая дата продажи*/
curr_oper /*текущая продажа, ключ*/
not_sale /*остаток товара*/
for
select ...
from operation
where <все операции прихода по выбранным товарам за требуемый период>
order by item, date_oper
into <переменные>
do
begin
while not_sale >0
do
begin
/*берем первый расход по данному товару*/
select first 1 ...
from operation
where <расход по выбранному товару за требуемый период при этом берем больше текущей даты и больше текущей опреции расхода, чтоб не зациклится>
order by date_oper, id_oper
into <переменные>;
/*закрываем приход расходом, пока есть ненулевой остаток, как только попытка превысить прокручиваемся на следущую запись в приходе и пошли по новой, попутно продвигаем текущую дату продажи и текущий остаток*/
suspend;
end
end
Алгоритм где-то так, можно вместо while+first сделать for select, в принципе. Как это запихнуть в один запрос пока не представляю.
Если делать на клиенте, я бы сделал два датасэта и прокручивал бы их за один проход параллельно, вот БЫ сделать такой финт в ХП. Хотя мож я просто от жизни поотстал и уже можно...
Сразу скажу - пост и алгоритм не читал.Ivan_Pisarevsky писал(а):Если делать на клиенте, я бы сделал два датасэта и прокручивал бы их за один проход параллельно, вот БЫ сделать такой финт в ХП. Хотя мож я просто от жизни поотстал и уже можно...
Если проход без возврата на предыдущие записи - то курсоры в 2-ке и старше - самое то
Спасибо всем огромное за помощь, задачу победил но пришлось действовать весьма нерацональным способом:
Создал новую таблицу RESULTS, куда сводятся сделки по продаже и соответсвующие им по покупке (внешний ключ), с явным указанием количества. Также в табличку оператион добавил поле SELL_VOLUME, куда вносится объем продажи и соответственно если объем продажи равняется объему покупки то больше эта строка не участвует.
Вобщем все работает но понимаю что далеко не идеальный вариант.
Кстати все таки интерес к реализации без дополнительной таблицы остался
Создал новую таблицу RESULTS, куда сводятся сделки по продаже и соответсвующие им по покупке (внешний ключ), с явным указанием количества. Также в табличку оператион добавил поле SELL_VOLUME, куда вносится объем продажи и соответственно если объем продажи равняется объему покупки то больше эта строка не участвует.
Вобщем все работает но понимаю что далеко не идеальный вариант.
Кстати все таки интерес к реализации без дополнительной таблицы остался
-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34