Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Обычная тема Разложение по партиям (число прочтений - 4448 )
quest
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 19
Зарегистрирован: 21. Августа 2006
Разложение по партиям
16. Ноября 2006 :: 11:47
Печать  
Есть 3 таблицы
ПартияОстатки (КодТовара,КодПартии,Количество,СумммаЗакупа,СуммаПродажи)
ПартияДвижения
(КодТовара,КодПартии,Количество,СумммаЗакупа,СуммаПродажи)
и ТаблицаРасходнаяНакладная
(КодТовара, Количество,Сумма)


заполненены примерно так

ПартияОстатки
КодТовара,КодПартии,Количество,СумммаЗакупа,СуммаПродажи
1,         1,         2,          5,          0
1,         2,         5,          20,         0

ТаблицаРасходнаяНакладная
КодТовара, Количество,Сумма
1,          6,          100

Надо провести в Партии так

ПартияДвижения
КодТовара,КодПартии,Количество,СумммаЗакупа,СуммаПродажи
1,          1,       2,             5,         (100/6)*2
1,          2,       4,             (20/5)*4,  (100/6)*4

У меня только одна мысль - бежать по курсору. Но можно ли это сделать одним запросом? или нет? Если можно то как?
  
Наверх
 
IP записан
 
ADirks
1c++ developer
1c++ moderator
Отсутствует


А нужны ли мы нам?

Сообщений: 692
Местоположение: Новосибирск
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Разложение по партиям
Ответ #1 - 16. Ноября 2006 :: 11:56
Печать  
Да, было бы здорово поиметь методу разбиения по партиям одним запросом. А то курсоры немножко напрягают. Тем более что их надо 2: по товарам и по партиям.
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разложение по партиям
Ответ #2 - 16. Ноября 2006 :: 13:14
Печать  
В порядке бреда Ужас
Код
Выбрать все
-- итоги по партиям
create table #Summs (
    DT datetime,	 -- дата прихода
    Qty numeric(19, 5) -- тек. остаток
)

-- тестовые данные
insert #Summs values ('20060101', 0)
insert #Summs values ('20060102', 0)
insert #Summs values ('20060103', 3)
insert #Summs values ('20060104', 3)
insert #Summs values ('20060105', 3)
insert #Summs values ('20060106', 5)
insert #Summs values ('20060107', 6)

-- переменные
declare @n1 numeric(19, 5)
declare @n2 numeric(19, 5)

set @n1 = 10 -- списать 10 ед.
set @n2 =  0 -- служебная (пром. итог)

-- служебная (расчёт итогов)
create table #tmp (
    DT datetime,
    Qty numeric(19, 5),
    Sub numeric(19, 5) default 0, -- к списанию
unique clustered (DT) -- индекс, определяющий порядок обхода партий
			    -- (метод расчёта себестоимости)
)

-- выборка партий
insert #tmp (DT, Qty)
select *
from #Summs
where Qty > 0

-- расчёт количества к списанию
update #tmp
set @n2 = Sub = case when Qty > @n1 then @n1 else Qty end,
    @n1 = @n1 - @n2

-- получение результата
select *
from #tmp
where Sub > 0

-- финиш
drop table #Summs
drop table #tmp 

  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
quest
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 19
Зарегистрирован: 21. Августа 2006
Re: Разложение по партиям
Ответ #3 - 16. Ноября 2006 :: 15:41
Печать  
Количество списываемого товара может быть больше чем есть по партионному учету на момент проведения документа. Доступных партий может быть больше 2. Метод списания может быть по среднему.

Может действительно, как-то по другому организовать структуры данных?
  
Наверх
 
IP записан
 
quest
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 19
Зарегистрирован: 21. Августа 2006
Re: Разложение по партиям
Ответ #4 - 20. Ноября 2006 :: 08:28
Печать  
В порядке бреда тоже. То что родилось на выходных
use test
go
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[testPartiya]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[testPartiya]
GO

CREATE TABLE [dbo].[testPartiya] (
     [id] [int] IDENTITY (1, 1) NOT NULL , --уникальный последовательно возрастающий с шагом 1 индекс номера партии
     [idPartiya] [int] NOT NULL , -- номер партии
     [value] [int] NOT NULL , -- сколько по этой партии осталось
     [upSum] [int] NOT NULL , -- сумма нарастающим итогом согласно сортировке id (пока только для возрастающей)
     [seb] [float] NOT NULL  -- себестоимость
) ON [PRIMARY]
GO

insert into testPartiya (idpartiya,value,upsum,seb) values (1,2,2,10)
insert into testPartiya (idpartiya,value,upsum,seb) values (2,3,5,11)
insert into testPartiya (idpartiya,value,upsum,seb) values (3,4,9,12)
insert into testPartiya (idpartiya,value,upsum,seb) values (4,5,19,13)
insert into testPartiya (idpartiya,value,upsum,seb) values (5,6,25,14)

declare @howNeed int
declare @howCost int
declare @howCostOne float
set @howNeed= 21 -- это сколько хотим разложить
set @howCost = 111
set @howCostOne = (convert(float,@howCost))/@howNeed



select z.idPartiya,z.seb/z.howGet,z.howGet,z.howGet*@howCostOne as ReadlCost from (
select id,idPartiya,seb,
howGet =
     case (idPartiya)
           when (1+(select max(id) from testPartiya where upSum<@howNeed)) then (value - (upSum-@howNeed))      else value end
from testPartiya where
id <= 1+(select max(id) from testPartiya where upSum<@howNeed)
) z


результат

1      5.0      2      10.571428571428571
2      3.6666666666666665      3      15.857142857142858
3      3.0      4      21.142857142857142
4      2.6000000000000001      5      26.428571428571427
5      7.0      2      10.571428571428571


ограничения - не обрабатывает ситуацию когда @howNeed  больше чем всего доступно товара, требует что бы id был заполнен без пробелов (не знаю чем занменить конструкцию 1+... в where), по скорости не могу оценить... Может на курсорах быстрее будет...

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


  
Наверх
 
IP записан
 
quest
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 19
Зарегистрирован: 21. Августа 2006
Re: Разложение по партиям
Ответ #5 - 20. Ноября 2006 :: 08:29
Печать  
в этом примере сделлано упрощение по товару и складу - предпологается что есть всего 1 товар и 1 склад.

там добавить нужных уловий в фильтре - труда не составит  Смех
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разложение по партиям
Ответ #6 - 20. Ноября 2006 :: 10:17
Печать  
quest писал(а) 20. Ноября 2006 :: 08:28:
В общем закритикуйте и скажите где можно улучшить...

Не показано заполнение поля upSum.

А ситуация, "когда @howNeed  больше чем всего доступно товара", IMHO, должна обрабатываться процедурой списания, а не процедурой выборки остатков.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
quest
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 19
Зарегистрирован: 21. Августа 2006
Re: Разложение по партиям
Ответ #7 - 20. Ноября 2006 :: 10:42
Печать  
upsum в примере - ручками посчитан.  Смех

По идее надо так


if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[testpartiya]') and objectproperty(id, N'isusertable') = 1)
drop table [dbo].[testpartiya]
go

create table [dbo].[testpartiya] (
     [id] [int] identity (1, 1) not null , --уникальный последовательно возрастающий с шагом 1 индекс номера партии
     [idpartiya] [int] not null , -- номер партии
     [value] [int] not null , -- сколько по этой партии осталось
     [seb] [float] not null,  -- себестоимость
     [upsum] [int] default 0 not null , -- сумма нарастающим итогом согласно сортировке id (пока только для возрастающей)
) on [primary]
go

insert into testpartiya (idpartiya,value,seb,upsum) values (1,2,10,1)
insert into testpartiya (idpartiya,value,seb,upsum) values (2,3,11,1)
insert into testpartiya (idpartiya,value,seb,upsum) values (3,4,12,1)
insert into testpartiya (idpartiya,value,seb,upsum) values (4,5,13,1)
insert into testpartiya (idpartiya,value,seb,upsum) values (5,6,14,1)


update testpartiya
     set upsum = (select isnull(sum(value),0)from testpartiya z where z.id<=id)

но этот update правильно не работет. Везде пишет одно число.
Хотя приведенный ниже  селект все корректно делает

select *,(select isnull(sum(value),0)from testpartiya z where z.id<=t.id) from testpartiya t

я так понимаю что проблема в том что в апдейте должен быть тоже алиас при расчете суммы. Но как его сделать - не знаю....  Смущённый
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Разложение по партиям
Ответ #8 - 20. Ноября 2006 :: 11:17
Печать  
Код
Выбрать все
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[testpartiya]') and objectproperty(id, N'isusertable') = 1)
drop table [dbo].[testpartiya]
go

create table [dbo].[testpartiya] (
     [id] [int] identity (1, 1) not null , --уникальный последовательно возрастающий с шагом 1 индекс номера партии
     [idpartiya] [int] not null , -- номер партии
     [value] [int] not null , -- сколько по этой партии осталось
     [seb] [float] not null,  -- себестоимость
     [upsum] [int] default 0 not null , -- сумма нарастающим итогом согласно сортировке id (пока только для возрастающей)
unique clustered (id)
) on [primary]
go

insert into testpartiya (idpartiya,value,seb,upsum) values (1,2,10,0)
insert into testpartiya (idpartiya,value,seb,upsum) values (2,3,11,0)
insert into testpartiya (idpartiya,value,seb,upsum) values (3,4,12,0)
insert into testpartiya (idpartiya,value,seb,upsum) values (4,5,13,0)
insert into testpartiya (idpartiya,value,seb,upsum) values (5,6,14,0)

declare @n int
set @n = 0

update testpartiya
set @n = @n + k.value, upsum = @n
from testpartiya k
where k.id <= id

select *,(select isnull(sum(value),0)from testpartiya z where z.id<=t.id) from testpartiya t  

  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
quest
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 19
Зарегистрирован: 21. Августа 2006
Re: Разложение по партиям
Ответ #9 - 20. Ноября 2006 :: 11:21
Печать  
Спасибо... Пошел учить матчасть...

Действительно, большое спасибо
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать