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

Откуда: Азербайджан, г. Баку
Сообщений: 1382
Есть записи в таблице со структурой
id int
cnt int (количество)
used int (количество использовано)

1 10 5
2 10 0
3 10 0
4 10 0
5 10 0

Нужно вычесть 30 из общего числа начиная с наименьшего id,
т.е. нужно получить

1 10 10
2 10 10
3 10 10
4 10 5
5 10 0

Как это правильно сделать?
23 апр 15, 14:22    [17554163]     Ответить | Цитировать Сообщить модератору
 Re: Как написать этот UPDATE ?  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Samir,

PRINT @@VERSION что возвращает?
23 апр 15, 14:34    [17554252]     Ответить | Цитировать Сообщить модератору
 Re: Как написать этот UPDATE ?  [new]
Samir
Member

Откуда: Азербайджан, г. Баку
Сообщений: 1382
iap
Samir,

PRINT @@VERSION что возвращает?


Microsoft SQL Server 2008 R2 (SP2
23 апр 15, 14:38    [17554275]     Ответить | Цитировать Сообщить модератору
 Re: Как написать этот UPDATE ?  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Samir,

это учебная задачка или рабочая система и записей - миллионы?
23 апр 15, 14:40    [17554285]     Ответить | Цитировать Сообщить модератору
 Re: Как написать этот UPDATE ?  [new]
Samir
Member

Откуда: Азербайджан, г. Баку
Сообщений: 1382
iap
Samir,

это учебная задачка или рабочая система и записей - миллионы?


Это так скажем склад, записей не миллионы, но пару тысяч будет.
Нужно просто проставить в накладных поставщика, сколько товара было использовано.
23 апр 15, 14:43    [17554313]     Ответить | Цитировать Сообщить модератору
 Re: Как написать этот UPDATE ?  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Просто у меня есть предположение, что как раз в этом случае наилучший выбор - курсор.
23 апр 15, 14:43    [17554315]     Ответить | Цитировать Сообщить модератору
 Re: Как написать этот UPDATE ?  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
Samir, есть как минимум один вопрос, который неплохо было бы прояснить, прежде чем делать update - что делать, если запрашиваемое количество больше доступного - в вашем примере - что будет, если запрошенное кол-во - 50, а не 30.
23 апр 15, 14:53    [17554390]     Ответить | Цитировать Сообщить модератору
 Re: Как написать этот UPDATE ?  [new]
Samir
Member

Откуда: Азербайджан, г. Баку
Сообщений: 1382
Minamoto
Samir, есть как минимум один вопрос, который неплохо было бы прояснить, прежде чем делать update - что делать, если запрашиваемое количество больше доступного - в вашем примере - что будет, если запрошенное кол-во - 50, а не 30.


С этим проблем нет, это легко проверяется. Если количество больше, чем есть в наличии - то далее процедура не будет работать.
23 апр 15, 14:56    [17554416]     Ответить | Цитировать Сообщить модератору
 Re: Как написать этот UPDATE ?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8839
Это задача вычисления нарастающего итога.
23 апр 15, 14:58    [17554427]     Ответить | Цитировать Сообщить модератору
 Re: Как написать этот UPDATE ?  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Владислав Колосов
Это задача вычисления нарастающего итога.
Вот только версия сервера неудачная для этого
23 апр 15, 14:59    [17554436]     Ответить | Цитировать Сообщить модератору
 Re: Как написать этот UPDATE ?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8839
iap,

увы. Но способы существуют и перечислены в FAQ...
23 апр 15, 15:03    [17554470]     Ответить | Цитировать Сообщить модератору
 Re: Как написать этот UPDATE ?  [new]
Кот Матроскин
Member

Откуда: Москва
Сообщений: 8933
предполагается что ID в таблице идут последовательно

declare @t table ( id int,
                   qty int,
                   used int)
                   
 declare @qty int
 
 select  @qty = 30                
                   
 insert @t (id, qty, used)
  values (1, 10, 5),
           (2, 10, 0 ),
           (3, 10, 0),
           (4, 10, 0),
           (5, 10, 0)  
           
           
   with cte (id, qty, used, rest )
   as
   (select  0, 0, 0, @qty 
    union all
    select t.ID, t.qty,case when t.Used + c.rest  < t.Qty
                                  then  t.Used + c.rest 
                              else t.Qty  
                        end,
                c.rest -  (case when t.Used + c.rest  < t.Qty
                                  then  c.rest 
                              else t.Qty - t.used 
                        end)
    from @t t
         join cte c
         on t.id =  c.id + 1                    
   )        

   update t
      set used = c.used
   from @t t
        join cte c
        on c.id = t.id

  select *
  from @t                
                             
23 апр 15, 15:04    [17554479]     Ответить | Цитировать Сообщить модератору
 Re: Как написать этот UPDATE ?  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
Кот Матроскин, нет никакой необходимости в последовательности ID.

Мой вариант:

--Исходные данные
declare @sklad table (id int, cnt int, used int);

insert into @sklad (id, cnt, used)
values (1, 10, 5), (2, 10, 0), (3, 10, 0), (4, 10, 0), (5, 10, 0);

declare @needed int = 30;

--Собственно скрипт
select	s1.id
	,	sum(s2.cnt - s2.used) as ost --это остаток до текущего ID включительно
	,	case when sum(s2.cnt - s2.used) < @needed then 0 else sum(s2.cnt - s2.used) - @needed end
		-- это количество, которое должно остаться в текущей записи
from @sklad s1
	inner join @sklad s2
			on s1.id >= s2.id

group by s1.id, s1.cnt, s1.used
having sum(s2.cnt - s2.used) < @needed + (s1.cnt - s1.used)


Это просто селект, как сделать из него update, надеюсь, объяснять не надо.
23 апр 15, 15:07    [17554510]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить