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

Откуда: Moscow
Сообщений: 178
SET @prevValue=0

update #temp set [Отношение] = ISNULL(([ВсяПрибыль]/nullif(@prevValue,0)),0), @prevValue = ISNULL([ВсяПрибыль],0) from #temp 





в какой последовательности обновляются столбцы?

проблема в том, что @prevValue для [Отношение] подставляется не равный 0, а равный ISNULL([ВсяПрибыль],0)

а мне нужно, чтобы первый раз подставился 0.


----------------------------------------------------
Microsoft SQL Server 2008 (SP1) - 10.0.2531.0 (Intel X86) Mar 29 2009 10:27:29 Copyright (c) 1988-2008 Microsoft Corporation Express Edition with Advanced Services on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)
7 ноя 09, 03:08    [7895848]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
слоненок
Member

Откуда:
Сообщений: 479
Aleksey_P, что вы хотели сказать, что значит "первый раз"?
7 ноя 09, 03:33    [7895863]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
aleks2
Guest
Порядок исполнения UPDATE неопределен. Хотя, обычно, простые UPDATE идут в порядке кластерного индекса.

Но рассчитывать на это - дурной тон.

В данном случае - CTE спасет отца русской демократии.

Ну... или identity, ежели это SQL2000.

>>в какой последовательности обновляются столбцы?
Тебе шо, попробовать переставить лень?
7 ноя 09, 10:28    [7896038]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31204
aleks2
Порядок исполнения UPDATE неопределен. Хотя, обычно, простые UPDATE идут в порядке кластерного индекса.

Но рассчитывать на это - дурной тон.

В данном случае - CTE спасет отца русской демократии.

Ну... или identity, ежели это SQL2000.
Автор спрашивал про столбцы, а не про строки. Т.е. сначала вычислится [Отношение] = ... или @prevValue = ...
aleks2
Тебе шо, попробовать переставить лень?
Желательно получить документальное подтверждение.

Я думаю, что слева направо, но в доке подтверждения этому не нашёл.
7 ноя 09, 12:45    [7896257]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
Aleksey_P
Member

Откуда: Moscow
Сообщений: 178
слоненок
Aleksey_P, что вы хотели сказать, что значит "первый раз"?


задача изначально следующая:

Расчитать во сколько раз менялась ВсяПрибыль из года в год
Таблица
Год ВсяПрибыль
2006 10
2007 15
2008 35

и третий столбец должен показать отношения.
первый раз значит, что первая "ВсяПрибыль" (в первой строке) имеет отношение равным null или ноль (неважно)
7 ноя 09, 12:54    [7896276]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
Aleksey_P
Member

Откуда: Moscow
Сообщений: 178
aleks2

Тебе шо, попробовать переставить лень?


нет конечно. я переставлял.
7 ноя 09, 12:54    [7896280]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
Влом регистрироваться
Guest
Aleksey_P,

доставайте значение за предыдущий год подзапросом, да и все.
7 ноя 09, 12:56    [7896285]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
Aleksey_P
Member

Откуда: Moscow
Сообщений: 178
Влом регистрироваться
Aleksey_P,

доставайте значение за предыдущий год подзапросом, да и все.


у меня могут быть разные периоды: годы, месяца, месяца могут идти не подряд(отпуск, праздники и тд.). или это можно обойти?
7 ноя 09, 13:01    [7896300]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
Влом регистрироваться
Guest
Aleksey_P,

вы не можете вычислить предыдущий год, квартал, месяц, рабочий день?
7 ноя 09, 13:15    [7896326]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
Aleksey_P
Member

Откуда: Moscow
Сообщений: 178
Влом регистрироваться
Aleksey_P,

вы не можете вычислить предыдущий год, квартал, месяц, рабочий день?


если такая последовательность: 5, 7, 12 то ниразу не приходилось делать.
7 ноя 09, 13:17    [7896333]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
iljy
Member

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

простой эксперимент
declare @t table(a int, b int, c int)
insert into @t values(1,2,3),(null,4,5),(6,null,7)
select * from @t

declare @b int

update @t
--set @b=b, a=@b
set a=@b, @b=b

select * from @t
показывает, что порядок столбцов в списке не влияет на результат, и в общем-то понятно почему - переменные вычисляются Table Scan -Compute Scalar, а значения записываются при Table Update. А обойти можно например так:
declare @t table(id int primary key, a int, b int, c int)
insert into @t values(1,1,2,3),(2,null,4,5),(3,6,null,7)
select * from @t

declare @b int

with cte as
( select ROW_NUMBER() over(order by id) N, * from @t)
update t1
--set @b=b, a=@b
set a=t2.b
from cte t1 left join cte t2 on t2.N = t1.N+1
select * from @t

--второй вариант
update t1
set a=t2.b
from
@t t1
	outer apply
(
	select top 1 * from @t
	where id > t1.id
	order by id asc
)t2
select * from @t
7 ноя 09, 13:18    [7896337]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
Aleksey_P
Member

Откуда: Moscow
Сообщений: 178
короче я сделал так, врогде работает
добавил в #temp столбец i int IDENTITY(1,1)
update #temp set [Отношение] = 1 where i=1
update #temp set [Отношение] = [ВсяПрибыль] / (select top(1) [ВсяПрибыль] from #temp t2 where t2.i<t1.i order by t2.i desc) from #temp t1 where i>1

----------------------------------------------------
Microsoft SQL Server 2008 (SP1) - 10.0.2531.0 (Intel X86) Mar 29 2009 10:27:29 Copyright (c) 1988-2008 Microsoft Corporation Express Edition with Advanced Services on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)
7 ноя 09, 15:11    [7896508]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
iljy
Member

Откуда:
Сообщений: 8711
Aleksey_P
короче я сделал так, врогде работает
добавил в #temp столбец i int IDENTITY(1,1)
update #temp set [Отношение] = 1 where i=1
update #temp set [Отношение] = [ВсяПрибыль] / (select top(1) [ВсяПрибыль] from #temp t2
 where t2.i<t1.i order by t2.i desc) from #temp t1 where i>1

----------------------------------------------------
Microsoft SQL Server 2008 (SP1) - 10.0.2531.0 (Intel X86) Mar 29 2009 10:27:29 Copyright (c) 1988-2008 Microsoft Corporation Express Edition with Advanced Services on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)


вы рисковый человек! во-первых - нет никаких гарантий, что порядок identity хоть как-то совпадет с порядком возрастания или убывания даты (вам ведь по дате надо предыдущее?), и никаких сообщений об ошибке вы в этом случае не получете, так что проще и надежнее делать подзапрос непосредственно по дате, или как вы определяете предыдущее. А во-вторых - на хоть сколько нибудь значительном количестве записей быстродействие у вас будет никакое.
7 ноя 09, 20:29    [7897033]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
isnull or not isnull
Guest
Aleksey_P,

ваш запрос 1) лишен смысла 2) вы пытаетесь использовать недокументированную особенность SQLServer, что само по себе зло, но даже и пытаетесь неправильно 3) если уж вам какой-то порядок нужен, то начните с изучения ORDER BY, а там видно будет.
8 ноя 09, 01:24    [7897613]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
Aleksey_P
Member

Откуда: Moscow
Сообщений: 178
iljy
Aleksey_P
короче я сделал так, врогде работает
добавил в #temp столбец i int IDENTITY(1,1)
update #temp set [Отношение] = 1 where i=1
update #temp set [Отношение] = [ВсяПрибыль] / (select top(1) [ВсяПрибыль] from #temp t2
 where t2.i<t1.i order by t2.i desc) from #temp t1 where i>1

----------------------------------------------------
Microsoft SQL Server 2008 (SP1) - 10.0.2531.0 (Intel X86) Mar 29 2009 10:27:29 Copyright (c) 1988-2008 Microsoft Corporation Express Edition with Advanced Services on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)


вы рисковый человек! во-первых - нет никаких гарантий, что порядок identity хоть как-то совпадет с порядком возрастания или убывания даты (вам ведь по дате надо предыдущее?), и никаких сообщений об ошибке вы в этом случае не получете, так что проще и надежнее делать подзапрос непосредственно по дате, или как вы определяете предыдущее. А во-вторых - на хоть сколько нибудь значительном количестве записей быстродействие у вас будет никакое.


1. А когда порядок identity может не совпасть с порядком дат?
2. быстродействие в данном случае мне не критично.
3. я как далается подобный подзапрос по дате, если даты не по порядку? в факе я не нашел.
8 ноя 09, 18:41    [7898465]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
Aleksey_P
Member

Откуда: Moscow
Сообщений: 178
isnull or not isnull
Aleksey_P,

ваш запрос 1) лишен смысла 2) вы пытаетесь использовать недокументированную особенность SQLServer, что само по себе зло, но даже и пытаетесь неправильно 3) если уж вам какой-то порядок нужен, то начните с изучения ORDER BY, а там видно будет.


1) почему? результат то я получил верный.
2) а что именно не документировано?
8 ноя 09, 18:46    [7898471]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
iljy
Member

Откуда:
Сообщений: 8711
Aleksey_P

1. А когда порядок identity может не совпасть с порядком дат?
2. быстродействие в данном случае мне не критично.
3. я как далается подобный подзапрос по дате, если даты не по порядку? в факе я не нашел.


1.порядок identity определяется порядком вставки в таблицу. Так что у вас появляется еще один существенный момент, который надо внимательно отслеживать, чтобы вставка шла строго в порядке возрастания дат. А плодить такие моменты без необходимости не стоит.
2. Не кажи гоп. Вот такие запросы
-- Первый
;with cte as
(
	select ROW_NUMBER() over(order by date) N, *
	from tt
)
update t1
set value1 = t2.value2
from cte t1 left join cte t2 on t1.N = t2.N+1

--Второй
update t1
set value1 = (select top 1 value2 from tt t2 where DATE < t1.date order by DATE desc)
from tt t1
выполняются на таблице
CREATE TABLE [dbo].[tt](
	[date] datetime primary key,
	value1 float,
	value2 float
) ON [PRIMARY]
из 10000
;with cte as
(
	select ROW_NUMBER() over(order by (select 1)) N
	from master..spt_values t1, master..spt_values t2, master..spt_values t3
)
insert into TT 
select top 10000 dateadd(minute, N, 0), sin(rand() * N + N%43), sin(rand() * (N-1) + N%78)
from cte
записей

------- Первый-----
Таблица "tt". Число просмотров 2, логических чтений 20086, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "Worktable". Число просмотров 0, логических чтений 0, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.

Время работы SQL Server:
Время ЦП = 172 мс, затраченное время = 203 мс.

(10000 row(s) affected)
------- Второй-----
Таблица "tt". Число просмотров 2, логических чтений 20086, физических чтений 0, упреждающих
чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "Worktable". Число просмотров 2, логических чтений 259520, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.

Время работы SQL Server:
Время ЦП = 19641 мс, затраченное время = 19866 мс.

(10000 row(s) affected)
На 100000 выполнения второго я не дождался
3.
set value1 = (select top 1 value2 from tt t2 where DATE < t1.date order by DATE desc)
а в чем собственно проблема? В чем отличие в использовании для поиска int и datetime?
8 ноя 09, 19:34    [7898572]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
Aleksey_P
Member

Откуда: Moscow
Сообщений: 178
1. Даты вставляются по порядку отдельным отсортированным запросом

insert into #temp ([Год],[ВсяПрибыль])
SELECT 'Год', 'ВсяПрибыль'
FROM [dbo].[данные]
group by [Год]
order by [Год]

так не надежно?
2. Да ну что вы, я столько не проживу. 10 тыс лет :)

3. Да вы правы. Я уже сам об этом подумал. С месяцами только проблема выскочит. Нужно будет их с годами склеивать.
8 ноя 09, 19:46    [7898593]     Ответить | Цитировать Сообщить модератору
 Re: Последовательность в set  [new]
iljy
Member

Откуда:
Сообщений: 8711
Aleksey_P
1. Даты вставляются по порядку отдельным отсортированным запросом

insert into #temp ([Год],[ВсяПрибыль])
SELECT 'Год', 'ВсяПрибыль'
FROM [dbo].[данные]
group by [Год]
order by [Год]

так не надежно?
2. Да ну что вы, я столько не проживу. 10 тыс лет :)

3. Да вы правы. Я уже сам об этом подумал. С месяцами только проблема выскочит. Нужно будет их с годами склеивать.

1. Ну по идее работать будет, хотя в документации это ситуация не особо описана, т.е. примеры такие есть, а вот больше ничего не сказано. Я предпочитаю такими конструкциями не пользоваться, а ну как чего поменяется - ищи потом! Да и просто - надо помнить всегда, что в эту таблицу вставлять только в таком порядке, а ну как функционал будет расти? Мозг - он не бесконечный Не умножайте сущностей без необходимости.
2. Да ладно, какие ваши годы;) и потом - ситуация отнюдь не уникальная, так что осваивайте правильные техники сразу. Подзапросы - вещь в принципе специфическая в плане быстродействия, злоупотреблять не стоит.
3. Ээээ... а где у вас месяцы - раз, и почему будет проблемой сравнить по месяцам - два? Дата - она все сразу содержит!
8 ноя 09, 21:30    [7898898]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить