Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
"Скажи Нет курсорам и циклам" SergSuper
|
|||
|---|---|---|---|
|
#18+
Нужно получить сумму (разность, что угодно) поля с суммой (разностью и т.д.) полей предыдущих записей с накоплением. Ну хотя бы так: set nocount on declare @i as int create table t (i1 int, i2 int) select @i = 0 while @i < 5 begin select @i = @i + 1 insert t(i1) values (@i) end --select * from t select @i = 0 update t set @i = @i + i1, i2 = @i select * from t drop table t set nocount off Как для SQL Server 7 гарантированно получить требуемый порядок обработки строк. Например, order by t.i desc ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.04.2001, 15:01 |
|
||
|
"Скажи Нет курсорам и циклам" SergSuper
|
|||
|---|---|---|---|
|
#18+
set nocount on declare @i as int create table #t (id int identity(1,1), i1 int, i2 int null) select @i = 0 while @i < 5 begin select @i = @i + 1 insert #t(i1) values (@i) end select @i = 0 update t set i2=(Select SUM(i1) from #t tt where tt.id<=t.id) from #t t select * from #t drop table #t set nocount off Надеюсь, это то, что нужно было получить. С уважением, А.Степанов a_stepanov_2000@mail.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.04.2001, 15:39 |
|
||
|
"Скажи Нет курсорам и циклам" SergSuper
|
|||
|---|---|---|---|
|
#18+
Ну нельзя ж так серьёзно всё воспринимать Иногда с курсором действительно бывает получается быстрее. Это для случаев когда важен именно порядок записей. Но к сожалению очень часто народ использует курсоры, где им не место. Происходит это из-за привычек работать по записям в Фоксе или Аксесе. Чем мне не нравяться курсоры, так это тем, как они убого реализованы. Вместо того чтобы сделать некую конструкцию типа FOR EACH, приходить самому организовывать цикл, читать в переменные, следить за его окончанием. Допустим у нас есть курсор declare c cursor for select i1 from t Вместо того чтобы написать как-нибудь for_each c into @i select @i2=@i2+@i я должен писать: open c fetch c into @i while @Fetch_Status=0 begin select @i2=@i2+@i fetch c into @i end Жутко смотриться если имеются вложенные циклы. Что касается Вашего вопроса. Если Вы пытаетесь доказать что в отдельных случаях без курсоров не обойтись - я переубеждать не буду, оставайтесь при своём мнении, к тому же я уже написал, что есть ситуации когда использование курсора предпочтительней. Но иногда лучше представить что нет курсоров и пытать как-то выкручиваться. В результате иногда удается найти более красивое решение. Что касается Вашей задачи. Вот так в лоб она не решается. Я обычно делал примерно так: set nocount on declare @i as int create table #t (i1 int, i2 int) select @i = 0 while @i < 5 begin select @i = @i + 1 insert #t(i1) values (@i) end select t1.i1, sum(t2.i1) i2 into #t0 from #t t1, #t t2 where t2.i1<=t1.i1 group by t1.i1 update #t set i2=t0.i2 from #t t1, #t0 t0 where t1.i1=t0.i1 select * from #t drop table #t drop table #t0 set nocount off Работать оно будет скорее всего медленнее чем с курсором, хотя если использовать паременные-таблицы - то не факт. Замечу еще что в SQL 4.0 и 6.0 синтаксис допускал конструкции без использования промежуточной таблицы. С приветом Сергей ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.04.2001, 15:51 |
|
||
|
"Скажи Нет курсорам и циклам" SergSuper
|
|||
|---|---|---|---|
|
#18+
2 SergSuper Ну что Вы, доказать я ничего не хочу. Как раз наоборот, пытаюсь уйти от встроенного курсора. 2Александр Степанов У меня нет уверенности, что identity(кстати и primary key, и clustered) гарантирует требуемый порядок обработки строк 2 All Увы, агрегатные функции не подходят, пользовательских в 7 нет. А логика такая (where t2.i1<=t1.i1 как то не пришить): create procedure dbo.MidPrice @old_quantity as float, @old_price as float, @new_quantity as float, @new_price as float, @sum_quantity as float output, @mid_price as float output as select @sum_quantity = @old_quantity + @new_quantity if @sum_quantity = 0 begin select @mid_price = 0 end else -- @sum_quantity <> 0 begin if @sum_quantity * @old_quantity < 0 begin select @mid_price = @new_price end else -- @sum_quantity * @old_quantity > 0 begin select @mid_price = abs((@old_price * @old_quantity + @new_price * @new_quantity) / @sum_quantity) end end go --end procedure dbo.MidPrice ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.04.2001, 16:27 |
|
||
|
"Скажи Нет курсорам и циклам" SergSuper
|
|||
|---|---|---|---|
|
#18+
Ну вообще если это SQL2000, то можно написать функцию. Будет выглядеть очень неплохо. Это случайно не расчет средней цены ценных бумаг? Кстати, а зачем писать каждый раз begin/end? Так же вроде наглядней: if @sum_quantity = 0 select @mid_price = 0 else -- @sum_quantity <> 0 if @sum_quantity * @old_quantity < 0 select @mid_price = @new_price else -- @sum_quantity * @old_quantity > 0 select @mid_price = abs((@old_price * @old_quantity + @new_price * @new_quantity) / @sum_quantity) или select @mid_price = case when @sum_quantity = 0 then 0 when @sum_quantity * @old_quantity < 0 then @new_price else abs((@old_price * @old_quantity + @new_price * @new_quantity) / @sum_quantity) end ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.04.2001, 17:55 |
|
||
|
"Скажи Нет курсорам и циклам" SergSuper
|
|||
|---|---|---|---|
|
#18+
>Ну вообще если это SQL2000, то можно написать функцию. Будет выглядеть очень неплохо. 7.0 >Это случайно не расчет средней цены ценных бумаг? Да >Кстати, а зачем писать каждый раз begin/end? Так же вроде наглядней: Привычка, так же как совать везде as и into Кстати, что думаете про топик "Встроенный курсор" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.04.2001, 18:05 |
|
||
|
"Скажи Нет курсорам и циклам" SergSuper
|
|||
|---|---|---|---|
|
#18+
про топик "Встроенный курсор" Ой тоскливо мне смотреть туда было. Это ж думать уже надо... Вобщем ничего не скажу, я сам курсоры раза 2-3 всего использовал. Я как увижу while @@fetch_status = 0 - плохо становиться ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.04.2001, 18:34 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32004756&tid=1826930]: |
0ms |
get settings: |
8ms |
get forum list: |
18ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
40ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
54ms |
get tp. blocked users: |
1ms |
| others: | 241ms |
| total: | 382ms |

| 0 / 0 |
