Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 И снова покрытие заявок.  [new]
minya13_85
Member

Откуда: Москва
Сообщений: 598
Есть таблица заявки:
create table  #Zayvka (Nomer INTEGER, Artikul NVARCHAR(10), [Количество] INTEGER,Data as varchar)
go
INSERT #Zayvka VALUES(123, N'01Б710030', 150,Август)
INSERT #Zayvka VALUES(123, N'01С712245', 100,Август)
INSERT #Zayvka VALUES(124, N'01Б710030', 150,Сентябрь)
INSERT #Zayvka VALUES(125, N'01Б710030',   50,Октябрь)

Есть таблица прихода по заявкам:

create table #Prihod (document INTEGER, Artikul NVARCHAR(10), [Количество] INTEGER, Proba integer,Data datetime)
go
INSERT #Prihod VALUES(4564, N'01Б710030',200,22.09.2009)
INSERT #Prihod VALUES(4564, N'01С712245', 30,22.09.2009)
INSERT #Prihod VALUES(4565, N'01Б710030', 40,30.09.2009)
INSERT #Prihod VALUES(4565, N'01К565423', 200,01.10.2009)
INSERT #Prihod VALUES(4566, N'01Б710030', 20,03.10.2009)

Хочу получить таблицу покрытие заявок, я думаю это метод LIFO

nomerАртикулМесяцЗаказПриходПокрытоОсталось покрытьЛишниеЗаявка
12301б710030Август150200150050Закрыта
12301С712245Август100303070-70Закрыта
12401б710030Сентябрь15011011040-40Открыта
12501б710030Октябрь500000Открыта


и до 25 октября, последние две заявки будут открыты, Если до 25 октября пришло еще несколько артикулов, то мы сначала покрываем сентябрь, потом октябрь. Август уже закрыт, мы не имеем право его покрывать, т.к. 25 сентября был последний срок.Допустим наступило 29 октября, и было еще два прихода. 20 октября и 28 октября на артикул 01Б710030. т.е.

create table #Prihod (document INTEGER, Artikul NVARCHAR(10), [Количество] INTEGER, Proba integer,Data datetime)
go
INSERT #Prihod VALUES(4564, N'01Б710030',200,22.09.2009)
INSERT #Prihod VALUES(4564, N'01С712245', 30,22.09.2009)
INSERT #Prihod VALUES(4565, N'01Б710030', 40,30.09.2009)
INSERT #Prihod VALUES(4565, N'01К565423', 200,01.10.2009)
INSERT #Prihod VALUES(4566, N'01Б710030', 20,03.10.2009)
INSERT #Prihod VALUES(4567, N'01Б710030', 30,20.10.2009)
INSERT #Prihod VALUES(4568, N'01Б710030', 70,28.10.2009)

Т.е. мы получим другую таблицу:
nomerАртикулМесяцЗаказПриходПокрытоОсталось покрытьЛишниеЗаявка
12301б710030Август150200150050Закрыта
12301С712245Август100303070-70Закрыта
12401б710030Сентябрь15014014010-10Закрыта
12501б710030Октябрь507050020Открыта


Т.е. закрытые заявки не могут уже измениться.

Версия
Microsoft SQL Server 2005 - 9.00.4035.00 (X64)   Nov 24 2008 16:17:31   Copyright (c) 1988-2005 Microsoft Corporation  Enterprise Edition (64-bit) on Windows NT 5.2 (Build 3790: Service Pack 2) 
5 окт 09, 12:37    [7742129]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
minya13_85
Member

Откуда: Москва
Сообщений: 598
minya13_85
Есть таблица заявки:
create table  #Zayvka (Nomer INTEGER, Artikul NVARCHAR(10), [Количество] INTEGER,Data as varchar)
go
INSERT #Zayvka VALUES(123, N'01Б710030', 150,Август)
INSERT #Zayvka VALUES(123, N'01С712245', 100,Август)
INSERT #Zayvka VALUES(124, N'01Б710030', 150,Сентябрь)
INSERT #Zayvka VALUES(125, N'01Б710030',   50,Октябрь)

Есть таблица прихода по заявкам:

create table #Prihod (document INTEGER, Artikul NVARCHAR(10), [Количество] INTEGER, Proba integer,Data datetime)
go
INSERT #Prihod VALUES(4564, N'01Б710030',200,22.09.2009)
INSERT #Prihod VALUES(4564, N'01С712245', 30,22.09.2009)
INSERT #Prihod VALUES(4565, N'01Б710030', 40,30.09.2009)
INSERT #Prihod VALUES(4565, N'01К565423', 200,01.10.2009)
INSERT #Prihod VALUES(4566, N'01Б710030', 20,03.10.2009)

Хочу получить таблицу покрытие заявок, я думаю это метод LIFO

nomerАртикулМесяцЗаказПриходПокрытоОсталось покрытьЛишниеЗаявка
12301б710030Август150200150050Закрыта
12301С712245Август100303070-70Закрыта
12401б710030Сентябрь15011011040-40Открыта
12501б710030Октябрь500000Открыта


и до 25 октября, последние две заявки будут открыты, Если до 25 октября пришло еще несколько артикулов, то мы сначала покрываем сентябрь, потом октябрь. Август уже закрыт, мы не имеем право его покрывать, т.к. 25 сентября был последний срок.Допустим наступило 29 октября, и было еще два прихода. 20 октября и 28 октября на артикул 01Б710030. т.е.

create table #Prihod (document INTEGER, Artikul NVARCHAR(10), [Количество] INTEGER, Proba integer,Data datetime)
go
INSERT #Prihod VALUES(4564, N'01Б710030',200,22.09.2009)
INSERT #Prihod VALUES(4564, N'01С712245', 30,22.09.2009)
INSERT #Prihod VALUES(4565, N'01Б710030', 40,30.09.2009)
INSERT #Prihod VALUES(4565, N'01К565423', 200,01.10.2009)
INSERT #Prihod VALUES(4566, N'01Б710030', 20,03.10.2009)
INSERT #Prihod VALUES(4567, N'01Б710030', 30,20.10.2009)
INSERT #Prihod VALUES(4568, N'01Б710030', 70,28.10.2009)

Т.е. мы получим другую таблицу:
nomerАртикулМесяцЗаказПриходПокрытоОсталось покрытьЛишниеЗаявка
12301б710030Август150200150050Закрыта
12301С712245Август100303070-70Закрыта
12401б710030Сентябрь15014014010-10Закрыта
12501б710030Октябрь507050020Открыта


Т.е. закрытые заявки не могут уже измениться.

Версия
Microsoft SQL Server 2005 - 9.00.4035.00 (X64)   Nov 24 2008 16:17:31   Copyright (c) 1988-2005 Microsoft Corporation  Enterprise Edition (64-bit) on Windows NT 5.2 (Build 3790: Service Pack 2) 
в таблице #Prihod, поле Proba не нужно..
5 окт 09, 12:39    [7742142]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
minya13_85
Member

Откуда: Москва
Сообщений: 598
Тут можно обойтись без курсоров?
5 окт 09, 13:55    [7742686]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
aleks2
Guest
minya13_85
Тут можно обойтись без курсоров?


Можно.
5 окт 09, 14:06    [7742764]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
minya13_85
Member

Откуда: Москва
Сообщений: 598
aleks2
minya13_85
Тут можно обойтись без курсоров?


Можно.
как?
5 окт 09, 14:09    [7742791]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
aleks2
Guest
minya13_85
aleks2
minya13_85
Тут можно обойтись без курсоров?


Можно.
как?


Ежели обойтись без курсоров самоцель - то тупо запросами в цикле.

Иначе - головой работать надо.
5 окт 09, 14:16    [7742842]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
minya13_85
Member

Откуда: Москва
Сообщений: 598
ну вы можете мне помочь решить данную задачу?
5 окт 09, 14:17    [7742848]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
aleks2
Guest
minya13_85
ну вы можете мне помочь решить данную задачу?

Помочь да, решать за вас - нет.

Итак, шо вы сделали и шо именно у вас не получилося?
5 окт 09, 14:24    [7742895]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
minya13_85
Member

Откуда: Москва
Сообщений: 598
Если честно, я пока не продумал алгоритм..Я вот думаю загнать таблицу Приход в курсор и построчно смотреть. Допустим я беру первую строку таблицы приход, соединяюсь с таблицей заявки по артикулу, и дате по месяцу меньше либо равно. (как ограничиться 25 числом каждого месяца еще не продумал). Допустим первой записи таблицы приход, соответствует две записи таблицы заявки и как эти 200 штук поделить между двумя записями, вот в чём загвоздка на данном этапе.
5 окт 09, 14:36    [7742981]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
Glory
Member

Откуда:
Сообщений: 104760
minya13_85
Если честно, я пока не продумал алгоритм..Я вот думаю загнать таблицу Приход в курсор и построчно смотреть. Допустим я беру первую строку таблицы приход, соединяюсь с таблицей заявки по артикулу, и дате по месяцу меньше либо равно. (как ограничиться 25 числом каждого месяца еще не продумал). Допустим первой записи таблицы приход, соответствует две записи таблицы заявки и как эти 200 штук поделить между двумя записями, вот в чём загвоздка на данном этапе.

Задача сводится к нумерации заявок и приходов в заданном периоде
С дальнешим соединением по этому периоду и номеру
Непонятно только, что у вас будет, когда суммы приходы периода превысят суммы заявок
5 окт 09, 14:40    [7743016]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
minya13_85
Member

Откуда: Москва
Сообщений: 598
Glory

Задача сводится к нумерации заявок и приходов в заданном периоде
С дальнешим соединением по этому периоду и номеру
Непонятно только, что у вас будет, когда суммы приходы периода превысят суммы заявок
нумерация подряд или каждая заявка начинается с новой нумерации и что мне это даст?
5 окт 09, 15:22    [7743323]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
minya13_85
Member

Откуда: Москва
Сообщений: 598
Можете помочь хотя бы просто в алгоритме. Я просто никак не могу придумать правильный алгоритм..((
5 окт 09, 15:24    [7743335]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
aleks2
Guest
minya13_85
Можете помочь хотя бы просто в алгоритме. Я просто никак не могу придумать правильный алгоритм..((

Алгоритм - это как раз то, что хотят услышать от вас.

Например:
1. Что считать "покрытием" заявки? Только приходы данного периода или остатки прошлых приходов тож?
2. Скока заявок могет быть в периоде: одна или несколько?
3. Ишо дохрена вопросов...
6 окт 09, 06:28    [7745812]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
minya13_85
Member

Откуда: Москва
Сообщений: 598
aleks2

Алгоритм - это как раз то, что хотят услышать от вас.
Например:
1. Что считать "покрытием" заявки? Только приходы данного периода или остатки прошлых приходов тож?
2. Скока заявок могет быть в периоде: одна или несколько?
3. Ишо дохрена вопросов...


1. Покрытие - это сколько заявлено артикула, столько и пришло. Остатки прошлых периодов не считать. заявки начали делать с 1 августа 2009 года, а приходы начались с 1 сентября 2009 года.
2. В периоде может быть очень много заявок, nomer - это id заявки. Один и тот же артикул может встречаться только один раз в одном месяце. в одной заявке может много разных артикулов.
и также с приходами, document - это id прихода, там только один и тот же артикул может встречаться в нескольких id прихода. в периоде также может быть очень много приходов.
3. Заявка выполняется ровно два месяца до 25 числа следующего месяца. Т.е. если на сентябрь, по одной заявке (например id заявки=123), заявили допустим артикула 01Б1111 - 200 штук. то мы смотрим приход за сентябрь по этому артикулу, и до 25 октября все приходы. Покрываем сначала приходом за сентябрь, эту заявку. допустим 12 сентября пришло это артикула 01Б1111 - 80 штук, мы эти 80 штук кидаем на эти 200, и получается что 80 покрыто - 120 не покрыто, потом допустим спустя пять дней 17 сентября по этому артикулу пришло еще 50 штук, то мы покрываем оставшиеся 120 штук, получается 130 покрыто-70 не покрыто. Допустим до 25 октября больше не было приходов. А был 27 октября по этому артикулу допустим 90 штук, то мы не можем этим приходом покрыть сентябрьскую заявку id=123. Т.е. мы эту заявку закрываем и видим что она не покрыта, т.е. на ней висит еще 70 штук. а этим приходом в 90 штук, мы покрываем уже октябрьскую заявку. Если в октябре не было заявки по данному артикулу, то смотрим другой артикул по данной заявке.
6 окт 09, 09:31    [7746035]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
aleks2
Guest
Это, канешно, не решение, но могет быть подвигнет на...
declare @Zayvka table ( Nomer INTEGER, Artikul NVARCHAR(10), [Количество] INTEGER, [Date] datetime
, id int identity primary key clustered)

INSERT @Zayvka VALUES(123, N'01Б710030', 150, '20090901')
INSERT @Zayvka VALUES(123, N'01С712245', 100, '20090901')
INSERT @Zayvka VALUES(124, N'01Б710030', 150, '20091001')
INSERT @Zayvka VALUES(125, N'01Б710030',  50, '20091101')

declare  @Prihod table(document INTEGER, Artikul NVARCHAR(10), [Количество] INTEGER, [Date] datetime
,id int identity primary key clustered)
  
INSERT @Prihod VALUES(4564, N'01Б710030',200,'20090922')
INSERT @Prihod VALUES(4564, N'01С712245', 30,'20090922')
INSERT @Prihod VALUES(4565, N'01Б710030', 40,'20090930')
INSERT @Prihod VALUES(4565, N'01К565423', 200,'20091001')
INSERT @Prihod VALUES(4566, N'01Б710030', 20,'20091003')

-- Веселенькое такое заявление:
-- "Заявка выполняется ровно два месяца до 25 числа следующего месяца"
-- Дык "два месяца" или "до 25 числа следующего месяца"?
declare @zMonths int
set @zMonths=2

-- связываем заявки с приходами
declare @ZP table(id int identity primary key clustered, zid int, pid int
, Artikul NVARCHAR(10)
, qZ int -- текущее кол-во заявки
, qP int -- текущее кол-во прихода
, rZ int -- остаток заявки 
, rP int -- остаток прихода 
, Z int -- удовлетворение заявки на момент ЭТОГО прихода
)
-- Создаем таблицу
insert @ZP(Artikul, zid, pid, qZ, qP, rZ, rP, Z)
select Z.Artikul, Z.ID, P.ID, 0, 0, 0, 0, 0
from @Zayvka Z
inner join
@Prihod P
ON Z.Date<=P.[Date] AND P.[Date]<DATEADD(month, @zMonths, Z.[Date]) AND Z.Artikul=P.Artikul
order by Z.Artikul, Z.Date, P.[Date]  

-- Заполняем начальными данными
UPDATE T SET qP=P.[Количество]
FROM @ZP T
INNER JOIN
@Prihod P
ON T.ID=P.ID
WHERE T.ID=(select min(id) FROM @ZP X WHERE X.pid=T.pid)

UPDATE T SET qZ=Z.[Количество]
FROM @ZP T
INNER JOIN
@Zayvka Z
ON T.ID=Z.ID
WHERE T.ID=(select min(id) FROM @ZP X WHERE X.zid=T.zid)

-- показываем шо получилося
select * FROM @ZP order by id

declare @ids table(id int primary key clustered, level int)
declare @rc int, @level int

-- колбасим НАЧАЛО ЦЕПОЧЕК
insert @ids(id,level)
select min(id) , 0
FROM @ZP
GROUP BY Artikul
set @rc=@@rowcount
set @level=0

-- колбасим выполнение заявок
while @rc>0 begin
  UPDATE T SET
   Z=(select min(x) FROM (select T.qZ+ISNULL(P.rZ,0) x UNION ALL SELECT T.qP+ISNULL(P.rP,0)) Z) --Удовл.Заявки
 , rP=T.qP+ISNULL(P.rP,0)-(select min(x) FROM (select T.qZ+ISNULL(P.rZ,0) x UNION ALL SELECT T.qP+ISNULL(P.rP,0)) Z) --Остаток Поступл
 , rZ=T.qZ+ISNULL(P.rZ,0)-(select min(x) FROM (select T.qZ+ISNULL(P.rZ,0) x UNION ALL SELECT T.qP+ISNULL(P.rP,0)) Z) --Остаток Заявки
  FROM 
    (select * FROM @ids WHERE level=@level) X
    INNER JOIN 
    @ZP T 
    ON X.ID=T.ID
    LEFT OUTER JOIN
    @ZP P
    ON P.id=T.ID-1 AND P.Artikul=T.Artikul

  insert @ids(id,level)
  select min(Y.id) , @level+1
  FROM
    (select * FROM @ids WHERE level=@level) X
    INNER JOIN 
    @ZP T 
    ON X.ID=T.ID
    INNER JOIN 
    @ZP Y 
    ON Y.Artikul=T.Artikul AND X.ID<Y.ID
  GROUP BY Y.Artikul
  
  set @rc=@@rowcount
  set @level=@level+1

end

select * FROM @ZP
Строить гипотезы далее мне неохота.
6 окт 09, 12:08    [7747123]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
minya13_85
Member

Откуда: Москва
Сообщений: 598
aleks2
Это, канешно, не решение, но могет быть подвигнет на...

Спасибо буду разбираться в коде


aleks2

-- Веселенькое такое заявление:
-- "Заявка выполняется ровно два месяца до 25 числа следующего месяца"
-- Дык "два месяца" или "до 25 числа следующего месяца"?

ну там как )) я не знаю почему так, но месяц у них начинается с 26 числа, это считается не конец месяца, а уже другой...и поэтому я говорю два месяца, заявка выполняется текущий месяц и следующий до 25 числа.
6 окт 09, 12:31    [7747302]     Ответить | Цитировать Сообщить модератору
 Re: И снова покрытие заявок.  [new]
minya13_85
Member

Откуда: Москва
Сообщений: 598
Что-то попытался написать, помогите немного отредактировать.
create table  #Zayvka (rang integer,order_id INTEGER, Artikul NVARCHAR(10), shtukZ INTEGER,mes integer)
go
INSERT #Zayvka VALUES(1,123, N'01Б710030', 150,8)
INSERT #Zayvka VALUES(2,123, N'01С712245', 100,8)
INSERT #Zayvka VALUES(3,124, N'01Б710030', 150,9)
INSERT #Zayvka VALUES(4,125, N'01Б710030', 50,10)

create table #Prihod (docid INTEGER, Artikul NVARCHAR(10), sht INTEGER, Data datetime)
go
INSERT #Prihod VALUES(4564, N'01Б710030',200,'2009-09-22')
INSERT #Prihod VALUES(4564, N'01С712245', 30,'2009-09-22')
INSERT #Prihod VALUES(4565, N'01Б710030', 40,'2009-09-30')
INSERT #Prihod VALUES(4565, N'01К565423', 200,'2009-10-01')
INSERT #Prihod VALUES(4566, N'01Б710030', 20,'2009-10-03')
INSERT #Prihod VALUES(4567, N'01Б710030', 30,'2009-10-20')
INSERT #Prihod VALUES(4568, N'01Б710030', 70,'2009-10-28')

declare  @pr table (id int identity(1,1),rang int,order_id  int,docid  int,Artikul nvarchar(20),shtZ int,shtP int,sht int,mes int)


DECLARE @Docid int, @Artikul nvarchar(20),@sht int, @Data datetime
DECLARE Prihod cursor for
select docid,Artikul,sht,Data
from #Prihod

open Prihod 
fetch next from Prihod into 
@Docid, @Artikul,@sht,@Data
WHILE @@FETCH_STATUS = 0
begin

insert into @pr (rang,order_id,docid,Artikul,shtZ,shtP,sht,mes)

select z.rang,z.order_id,@Docid,z.Artikul,z.shtukZ,@sht,@sht-z.shtukz,z.mes
from #Zayvka as z
where z.Artikul=@Artikul and ((case when day(@Data)<=25 then month(@Data) else month(@Data)+1 end) - z.mes) in (0,1)
--and z.rang not in (select rang from @pr)

update #Prihod set #Prihod.sht=pr.sht
from #Prihod inner join @pr as pr
on pr.Artikul=#Prihod.Artikul and pr.docid=#Prihod.docid
------помогите написать апдейт чтобы он на первом шаге проверял,т.е. проверил одну запись из заявки, если есть, сразу апдейтил штуки.

fetch next from Prihod into 
@Docid, @Artikul,@sht,@Data
end

select *
from @pr
order by order_id

CLOSE Prihod 
DEALLOCATE Prihod
drop table #Zayvka
drop table #Prihod
6 окт 09, 15:33    [7748708]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить