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

Откуда:
Сообщений: 149
Доброго времени суток!

Есть две таблица План и Факт

Таблица план:
id name plan
1 3НЦ1-В25 1
2 3НЦ1-В25 1
3 3НЦ1-В25 1
4 3НЦ1-В25 1
5 ВБ2-5 1
6 ВБ2-5 1
7 ВБ2-5 1


Таблица факт:
name fakt
3НЦ1-В25 3
ВБ2-5 1



Таблица результат:
id name plan x
1 3НЦ1-В25 1 1
2 3НЦ1-В25 11
3 3НЦ1-В25 11
4 3НЦ1-В25 10
5 ВБ2-5 11
6 ВБ2-5 10
7 ВБ2-5 10


Суть задачи в том чтобы распределить факт согласно плану.

Пояснение:
Каждая запись в таблице план уникальна, суммировать и группировать нельзя. Представленные таблицы сильно упрощены дабы не перегружать задачу лишней информацией.


На данный момент в таблице план более 5 тысяч уникальных записей, в таблице факт 146 записей.
Распределение я сделал с помощью цикла. Бегая по таблице план ищу соответствующую запись в таблице факт (по полю name), сравниваю план с фактом, отнимаю от факта план и до тех пор пока факт не станет равным 0.

Результат устраивает, не устраивает время выполнения запроса, а это порядка 10 секунд.
Крутил и так и сяк сделать быстрее не могу, может быть у кого то будут идеи алгоритма который будет работать на порядок быстрее.
7 окт 15, 13:37    [18246483]     Ответить | Цитировать Сообщить модератору
 Re: Как быстро распределить факт по плану  [new]
Добрый Э - Эх
Guest
используй оконную сумму для получения накопительного итога (в твоем случае - накопительного расхода факта...)
7 окт 15, 13:42    [18246542]     Ответить | Цитировать Сообщить модератору
 Re: Как быстро распределить факт по плану  [new]
fakt,
Guest
...P left join F on P.name=F.name and P.Row_Number_Partition_Name between 1 and F.fakt
7 окт 15, 13:53    [18246659]     Ответить | Цитировать Сообщить модератору
 Re: Как быстро распределить факт по плану  [new]
_djХомяГ
Guest
одно из решений с нараст итогом (как говорили выше)- возможны ошибки ....
ps наименование заменил на itemID - это не суть
declare @plan table (id int,itemId int,[plan] int )
insert into @plan 
select 1,1,1
union all 
select 2,1,1
union all
select 3,1,1
union all
select 4,1,1
union all
select 5,2,1
union all
select 6,2,1
union all
select 7,2,1



declare @fact table (itemid int,fact int)
insert into @fact
select 1,3
union all
select 2,1


;with cte 
as
(
   select itemid,id,[plan],(select sum([plan]) from @plan s1 where s.itemid=s1.itemid and s.id>=s1.id) as tot
   from @plan s 
)
select 
    
  c.itemid,c.id,
  case when s.fact-(tot-c.[plan])>c.[plan] then c.[plan]
         when s.fact-(tot-c.[plan])<0      then 0
       else s.fact-(tot-c.[plan])
  end as x
from cte c join @fact s 
on c.itemid=s.itemid
7 окт 15, 14:18    [18246901]     Ответить | Цитировать Сообщить модератору
 Re: Как быстро распределить факт по плану  [new]
RAVen42
Member

Откуда:
Сообщений: 149
Всем спасибо, так как у меня 2008 SQL, буду использовать CTE, _djХомяГ отдельное спасибо.
8 окт 15, 07:09    [18250360]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить