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

Встал такой вопрос: возможно ли в MS SQL Server написать запрос с декрементальным уменьшением одного из полей по значению другого поля, например выборка полей S,N,X, где известно, что изначальное значение X=50 и оно будет уменьшаться в каждой строке на N:

S   N    X
------------
a 2 48
b 1 47
c 10 37
d 6 31

и т.д. Если это возможно - будьте любезны, подскажите!
17 окт 13, 03:11    [14983252]     Ответить | Цитировать Сообщить модератору
 Re: Декремент по значению поля  [new]
faucet
Guest
Да, уточнение - Х не является полем таблицы, из которой делается выборка. Это параметр, а в принципе это начальное значение может быть даже и константой.
17 окт 13, 03:19    [14983253]     Ответить | Цитировать Сообщить модератору
 Re: Декремент по значению поля  [new]
Ruuu
Member

Откуда: Иркутск
Сообщений: 4272
faucet,

Динамическая нумерация строк в запросе SELECT языка Transact-SQL
17 окт 13, 05:09    [14983267]     Ответить | Цитировать Сообщить модератору
 Re: Декремент по значению поля  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31865
faucet
Если это возможно - будьте любезны, подскажите!
Версия то какая?
17 окт 13, 09:16    [14983513]     Ответить | Цитировать Сообщить модератору
 Re: Декремент по значению поля  [new]
invm
Member

Откуда: Москва
Сообщений: 9723
declare @t table (S char(1), N int);

insert into @t
values
 ('a', 2),
 ('b', 1),
 ('c', 10),
 ('d', 6);

declare @x int = 50;

select
 t1.S, t1.N, @x - sum(t2.N) as X
from
 @t t1 join
 @t t2 on t2.S<= t1.S
group by
 t1.S, t1.N
order by
 t1.S;

select
 t1.S, t1.N, @x - t2.X as X
from
 @t t1 cross apply
 (select sum(N) from @t where S <= t1.S) t2(X)
order by
 t1.S;

select
 t1.S, t1.N, @x - sum(t1.N) over (order by t1.S) as X
from
 @t t1
order by
 t1.S;
17 окт 13, 09:32    [14983574]     Ответить | Цитировать Сообщить модератору
 Re: Декремент по значению поля  [new]
faucet
Guest
У меня на тестовой машине установлена версия 8.00 под Win2000, но у пользователей, видимо, более современная версия, какая конкретно - не могу сказать.
17 окт 13, 19:23    [14987589]     Ответить | Цитировать Сообщить модератору
 Re: Декремент по значению поля  [new]
faucet
Guest
Ruuu, "Динамическая нумерация строк в запросе SELECT языка Transact-SQL" - насколько я вижу, там нечто иное. Там работа с автоинкрементом на 1, а мне нужно не на 1, а на число из поля таблицы.

invm, мне, к сожалению, не удалось запустить Ваш пример, даже на MS SQL Server 2008: ругается на строку:
 t1.S, t1.N, @x - sum(t1.N) over (order by t1.S) as X
такая вот ошибка: "Incorrent syntax near 'order'"
17 окт 13, 20:37    [14987800]     Ответить | Цитировать Сообщить модератору
 Re: Декремент по значению поля  [new]
invm
Member

Откуда: Москва
Сообщений: 9723
faucet
invm, мне, к сожалению, не удалось запустить Ваш пример, даже на MS SQL Server 2008: ругается на строку:
 t1.S, t1.N, @x - sum(t1.N) over (order by t1.S) as X

такая вот ошибка: "Incorrent syntax near 'order'"
Потому что это для SQL Server 2012.
Вариант для всех версий - первый.
17 окт 13, 20:56    [14987858]     Ответить | Цитировать Сообщить модератору
 Re: Декремент по значению поля  [new]
Гость333
Member

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

Только учтите, что на больших объёмах данных первые два варианта — очень грустные по производительности. Если данных много, лучше сделать через курсор/цикл.
18 окт 13, 11:13    [14996496]     Ответить | Цитировать Сообщить модератору
 Re: Декремент по значению поля  [new]
faucet
Guest
Спасибо! Да, первые два примера действительно замечательно работают... но вот я до сих пор немного не въехал в тему. Попытался усложнить задачу и разделить таблицы на 2 - в одной имена, в другой - количественные значения. Столкнулся в проблемой:
declare @t table (S char(1), ID int, D date);
declare @ti table (ID int, N int);

insert into @t values
 ('a', 1, '2000-02-02'),
 ('b', 2, '1999-12-12'),
 ('c', 3, '2009-01-01'),
 ('d', 4, '1990-02-02');

insert into @ti values
 (1, 2),
 (2, 1),
 (3, 10),
 (4, 6);

declare @X int;
set @X = 50;

select
  t1.S,
  ti1.N,
  @X - sum(ti2.N) as "X"
from
  @t t1
  join @ti ti1 on ti1.ID=t1.ID
  join @t t2 on t1.S<= t2.S
  join @ti ti2 on ti2.ID=t2.ID
--where
--  t1.D >= '2000-01-01'
group by
 t1.S,
 ti1.N
order by
 t1.S;


Чего-то я перемудрил видимо...
S   N   X
---------
a 2 31
b 1 33
c 10 34
d 6 44

Гость333, а вот с курсором я немного не понял - сколько ни смотрел, всё редактирования выборок делаются. А как же саму выборку вернуть типа как результат работы запроса SELECT?
18 окт 13, 12:48    [14997514]     Ответить | Цитировать Сообщить модератору
 Re: Декремент по значению поля  [new]
faucet
Guest
поменял в вышеприведённом коде
@X - sum(ti2.N) as "X"

на
@X - sum(ti1.N) as "X"

но всё равно результат не тот, что должен быть
18 окт 13, 12:51    [14997559]     Ответить | Цитировать Сообщить модератору
 Re: Декремент по значению поля  [new]
Гость333
Member

Откуда:
Сообщений: 3683
faucet
А как же саму выборку вернуть типа как результат работы запроса SELECT?

В каждой итерации цикла складывать полученные значения во временную таблицу или табличную переменную. В конце сделать SELECT.
18 окт 13, 12:54    [14997575]     Ответить | Цитировать Сообщить модератору
 Re: Декремент по значению поля  [new]
Гость333
Member

Откуда:
Сообщений: 3683
faucet
первые два примера действительно замечательно работают

Если пример с cross apply работает, значит, у вас как минимум MSSQL 2005. Что не совсем согласуется с
автор
У меня на тестовой машине установлена версия 8.00
18 окт 13, 12:55    [14997597]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить