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

Откуда:
Сообщений: 14
Добрый день всем,
Подскажите, пожалуйста, можно ли без использования курсора сгруппировать данные таблицы(по предпоследней колонке) по условию abs(Cost_change)>1.4. То есть, если цена изменяется более чем на 1.4, то группа=группа+1. Результат в последней колонке. Спасибо за внимание


Declare @s int
set @s=1
While (select abs(Cost_change) from Cost_prod)>1.4
Begin
insert into Cost_prod (Res)
select @S
set @s=@s+1
end

К сообщению приложен файл. Размер - 39Kb
27 авг 15, 11:05    [18075018]     Ответить | Цитировать Сообщить модератору
 Re: Группировка без курсора  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21253
RUSSIANBEAR7
можно ли без использования курсора сгруппировать данные таблицы(по предпоследней колонке) по условию abs(Cost_change)>1.4. То есть, если цена изменяется более чем на 1.4, то группа=группа+1. Результат в последней колонке.

Достаточно несложно в запросе получить поле, значение которого равно 1, если условие выполняется, и 0, если нет. Необходимый тебе номер группы - это тупо нарастающая сумма по этому полю при сортировке по ID.
27 авг 15, 11:11    [18075054]     Ответить | Цитировать Сообщить модератору
 Re: Группировка без курсора  [new]
o-o
Guest
вроде как с window functions нарастающий итог не так дорого считать стало,
но я бы лучше по-старинке: пронумеровать всех тех, у кого abs(Cost_change)>1.4
и сджойнить с исходной таблицей по полученным интервалам
27 авг 15, 11:25    [18075158]     Ответить | Цитировать Сообщить модератору
 Re: Группировка без курсора  [new]
o-o
Guest
declare @t table (id int, c_ch decimal(10,1));
insert into @t values (1, -1.5), (2, 3.7),
(3, -6.9), (4, 1.2), (5, 2.0), (6, 3.0), (7, -2.7),
(8, -1.3), (9, 0.1), (10, 0.9), (11, 0.3), (12, 7.5);

with gr as
(
select id, lead(id, 1, id + 1) over(order by id) as nxt_id,
       ROW_NUMBER() over(order by id) as rn
from @t
where abs(c_ch) > 1.4
)

select t.*, gr.rn
from @t t left join gr on t.id >= gr.id and t.id < gr.nxt_id
---
id	c_ch	rn
1	-1.5	1
2	3.7	2
3	-6.9	3
4	1.2	3
5	2.0	4
6	3.0	5
7	-2.7	6
8	-1.3	6
9	0.1	6
10	0.9	6
11	0.3	6
12	7.5	7
27 авг 15, 11:40    [18075310]     Ответить | Цитировать Сообщить модератору
 Re: Группировка без курсора  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21253
А, по-моему,
SELECT
  t.id
, t.c_ch
, 1 + SUM(CASE WHEN ABS(c_ch) > 1.4 THEN 1 ELSE 0 END) OVER (ORDER BY id) AS groupnumber
FROM @t t
попроще будет.
27 авг 15, 11:48    [18075386]     Ответить | Цитировать Сообщить модератору
 Re: Группировка без курсора  [new]
o-o
Guest
Akina
А, по-моему,
SELECT
  t.id
, t.c_ch
, 1 + SUM(CASE WHEN ABS(c_ch) > 1.4 THEN 1 ELSE 0 END) OVER (ORDER BY id) AS groupnumber
FROM @t t
попроще будет.

проще будет.
а будет ли быстрее, не могу сказать.
меня как-то тоже воодушевили эти window functions,
а потом как-то раз очень простое с виду решение с их применением
оказалось куда тормознее "классического" от aleks2.
причем у него была пара сканов, у меня всего 1, но зато очень симпатичный WINDOW SPOOL.
если вспомню, о чем шла речь, покажу картинку во весь экран :)
27 авг 15, 12:01    [18075510]     Ответить | Цитировать Сообщить модератору
 Re: Группировка без курсора  [new]
o-o
Guest
to Akina
вот оно: 16805364
1 обращение к таблице, на плане типа все отлично,
на деле тормоз.
может, по этому поводу выскажутся SomewhereSomehow или churupaha (он же window spool от случая к случаю).
я только могу констатировать факт и подозревать WINDOW SPOOL
27 авг 15, 12:47    [18075862]     Ответить | Цитировать Сообщить модератору
 Re: Группировка без курсора  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21253
o-o
вот оно: 16805364
1 обращение к таблице, на плане типа все отлично,
на деле тормоз

У тебя там 10кк записей и выражение в агрегатке - ещё бы не тормоза. Кстати, там у тебя вроде MAX() - тогда непонятно, нахрена в окне не только партиционирование, но ещё и сортировка.
Здесь, правда, тоже выражение, но записей на несколько порядков меньше, так что время выполнения будет на уровне максимум десятков мс, я полагаю.
27 авг 15, 12:59    [18075962]     Ответить | Цитировать Сообщить модератору
 Re: Группировка без курсора  [new]
o-o
Guest
Akina,

там задачка занимательная,
а мое решение -- извращенское,
это был спортивный интерес: можно ли воронинское решение хоть как-то присобачить.
если заняться нечем, почитайте еще раз задачку, прикольная, не сама по себе, а в свете
можно ли решить с применением window functions.
27 авг 15, 13:07    [18076033]     Ответить | Цитировать Сообщить модератору
 Re: Группировка без курсора  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21253
o-o
почитайте еще раз задачку, прикольная, не сама по себе, а в свете
можно ли решить с применением window functions.

Посмотрел... навскидку пока не вижу решения с оконной функцией, использующее одну копию исходной таблицы и не использующее подзапросы. Но помыслю (не в рамках 2005, который там у ТС, сабо самой).
И вроде вижу решение с использованием CTE. Но оно мне уже сейчас не нравится.
27 авг 15, 13:19    [18076177]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить