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

Откуда: Moscow
Сообщений: 179
Есть таблица, с полем Ord, по которому надо упорядочить результат запроса из этой таблицы, но при этом другое поле Val влияет на некое результирующе поле Ind, которое увеличивается каждый раз при смене поля Val.

Т.е. как из такой таблицы

Val Ord
11
12
33
34
35
106
107
38
39
1310
1311
1312
113
114
1315
1316
1317


+ t-sql таблицы

DECLARE @t1 TABLE ([Val] INT, [Ord] INT)

INSERT INTO @t1
SELECT * FROM (
SELECT 1 [Val], 1 [Ord]
UNION ALL
SELECT 1 [Val], 2 [Ord]
UNION ALL
SELECT 3 [Val], 3 [Ord]
UNION ALL
SELECT 3 [Val], 4 [Ord]
UNION ALL
SELECT 3 [Val], 5 [Ord]
UNION ALL
SELECT 10 [Val], 6 [Ord]
UNION ALL
SELECT 10 [Val], 7 [Ord]
UNION ALL
SELECT 3 [Val], 8 [Ord]
UNION ALL
SELECT 3 [Val], 9 [Ord]
UNION ALL
SELECT 13 [Val], 10 [Ord]
UNION ALL
SELECT 13 [Val], 11 [Ord]
UNION ALL
SELECT 13 [Val], 12 [Ord]
UNION ALL
SELECT 1 [Val], 13 [Ord]
UNION ALL
SELECT 1 [Val], 14 [Ord]
UNION ALL
SELECT 13 [Val], 15 [Ord]
UNION ALL
SELECT 13 [Val], 16 [Ord]
UNION ALL
SELECT 13 [Val], 17 [Ord]
) t

SELECT t.* FROM @t1 t ORDER BY t.[Ord]


получить вот такой результат

fInt fOrd fIndex
111
121
332
342
352
1063
1073
384
394
13105
13115
13125
1136
1146
13157
13167
13177
7 май 13, 18:31    [14269785]     Ответить | Цитировать Сообщить модератору
 Re: Индексирование СМЕНЫ значений поля в заданном порядке  [new]
MaratSH
Member

Откуда: Moscow
Сообщений: 179
Забыл добавить, что речь идет о получении результата одним запросом, т.е. не создание курсора и скролл по нему, а один цельный запрос, и не такой, чтобы делать N уровней вложенности, а максимально простой.
7 май 13, 18:36    [14269800]     Ответить | Цитировать Сообщить модератору
 Re: Индексирование СМЕНЫ значений поля в заданном порядке  [new]
Anddros
Member

Откуда:
Сообщений: 1077
declare @t table (ord int identity, val int)
insert @t values (1),(1),(3),(3),(3),(10),(10),(3),(3),(13),(13),(13),(1),(1),(13),(13),(13)

select ord, val, dense_rank()over(order by rn)ind 
from (select *, row_number()over(order by ord)-row_number()over(partition by val order by ord)rn from @t)t
7 май 13, 19:11    [14269890]     Ответить | Цитировать Сообщить модератору
 Re: Индексирование СМЕНЫ значений поля в заданном порядке  [new]
Владимир Затуливетер
Member

Откуда:
Сообщений: 427
declare @t table (ord int identity, val int)
insert @t values (1),(1),(3),(3),(3),(10),(10),(3),(3),(13),(13),(13),(1),(1),(13),(13),(13)

--sql server 2012
select val, ord, sum(nv) over(order by ord) as idx
from (
         select ord
              , val
              , iif(val = lag(val) over(order by ord), 0, 1) as nv
         from @t
       ) t
order by ord
7 май 13, 19:49    [14269979]     Ответить | Цитировать Сообщить модератору
 Re: Индексирование СМЕНЫ значений поля в заданном порядке  [new]
MaratSH
Member

Откуда: Moscow
Сообщений: 179
Anddros
declare @t table (ord int identity, val int)
insert @t values (1),(1),(3),(3),(3),(10),(10),(3),(3),(13),(13),(13),(1),(1),(13),(13),(13)

select ord, val, dense_rank()over(order by rn)ind 
from (select *, row_number()over(order by ord)-row_number()over(partition by val order by ord)rn from @t)t


Великолепно, спасибо большое! То, что надо! Мозгов мне не хватило ))

Владимир Затуливетер

вам тоже спасибо, интересный вариант, но пока не используем 2012-й...
7 май 13, 19:53    [14269983]     Ответить | Цитировать Сообщить модератору
 Re: Индексирование СМЕНЫ значений поля в заданном порядке  [new]
serpentariy
Member

Откуда:
Сообщений: 265
MaratSH
Anddros
declare @t table (ord int identity, val int)
insert @t values (1),(1),(3),(3),(3),(10),(10),(3),(3),(13),(13),(13),(1),(1),(13),(13),(13)

select ord, val, dense_rank()over(order by rn)ind 
from (select *, row_number()over(order by ord)-row_number()over(partition by val order by ord)rn from @t)t

Великолепно, спасибо большое! То, что надо! Мозгов мне не хватило ))

Вы сортировку по ord добавьте и сравните полученный результат с тем, что Вы в первом посте привели. Результаты не совсем совпадают.
7 май 13, 20:08    [14270006]     Ответить | Цитировать Сообщить модератору
 Re: Индексирование СМЕНЫ значений поля в заданном порядке  [new]
MaratSH
Member

Откуда: Moscow
Сообщений: 179
serpentariy
MaratSH
Великолепно, спасибо большое! То, что надо! Мозгов мне не хватило ))

Вы сортировку по ord добавьте и сравните полученный результат с тем, что Вы в первом посте привели. Результаты не совсем совпадают.


хм, да, точно, такой запрос из таких вот данных уже не верен
(заменил первые три тройки на единицы и добавил order by ord):

Ord Val
11
21
31
41
51
610
710
83
93
1013
1113
1213
131
141
1513
1613
1713


declare @t table (ord int identity, val int)
insert @t values (1),(1),([b]1[/b]),([b]1[/b]),([b]1[/b]),(10),(10),(3),(3),(13),(13),(13),(1),(1),(13),(13),(13)

select ord, val, dense_rank()over(order by rn)ind 
from (select *, row_number()over(order by ord)-row_number()over(partition by val order by ord)rn from @t)t
ORDER BY ord


получаем:

Ord Val Ind
111
211
311
411
511
6102
7102
833
933
10134
11134
12134
1313 (повтор)
1413 (повтор)
15135
16135
17135
8 май 13, 13:14    [14273275]     Ответить | Цитировать Сообщить модератору
 Re: Индексирование СМЕНЫ значений поля в заданном порядке  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
WITH T AS(SELECT * FROM(VALUES
 (1,1)
,(2,1)
,(3,1)
,(4,1)
,(5,1)
,(6,10)
,(7,10)
,(8,3)
,(9,3)
,(10,13)
,(11,13)
,(12,13)
,(13,1)
,(14,1)
,(15,13)
,(16,13)
,(17,13)
)T(Ord,Val))

SELECT Ord,Val,Ind=DENSE_RANK()OVER(ORDER BY M) FROM
(
 SELECT M=MIN(Ord)OVER(PARTITION BY N,Val),* FROM
 (
  SELECT N=ROW_NUMBER()OVER(ORDER BY Ord)-ROW_NUMBER()OVER(PARTITION BY Val ORDER BY Ord),*
  FROM T
 )T
)T
ORDER BY Ord;
8 май 13, 13:42    [14273434]     Ответить | Цитировать Сообщить модератору
 Re: Индексирование СМЕНЫ значений поля в заданном порядке  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
Производные таблицы (подзапросы) лучше оформить в виде CTE (через запятую).
Нагляднее как-то
8 май 13, 13:44    [14273445]     Ответить | Цитировать Сообщить модератору
 Re: Индексирование СМЕНЫ значений поля в заданном порядке  [new]
Anddros
Member

Откуда:
Сообщений: 1077
До кучи.

Экзотика, которая будет подтормаживать на больших данных:

declare @t table (ord int identity primary key, val int)
insert @t values (1),(1),(1),(1),(1),(10),(10),(3),(3),(13),(13),(13),(1),(1),(13),(13),(13)

select ord, val, dense_rank()over(order by (select max(ord) from @t t2 where t1.ord>t2.ord and t1.val<>t2.val)) from @t t1


declare @t table (ord int identity primary key, val int)
insert @t values (1),(1),(1),(1),(1),(10),(10),(3),(3),(13),(13),(13),(1),(1),(13),(13),(13)

;with q as (select (select str(ord,10)+str(val,10) from @t order by ord for xml path(''))+' 'ss, 0 ord, 0 ind, cast(null as int) val
union all
select stuff(ss,1,20,''),ord1,ind+case when val=val1 then 0 else 1 end,val1 
from q
cross apply (select cast(substring(ss,1,10) as int) ord1, cast(substring(ss,11,10) as int) val1)t 
where ord1>0)
select ord,val,ind 
from q 
where ord>0 
option (maxrecursion 0)
8 май 13, 14:14    [14273743]     Ответить | Цитировать Сообщить модератору
 Re: Индексирование СМЕНЫ значений поля в заданном порядке  [new]
MaratSH
Member

Откуда: Moscow
Сообщений: 179
iap
SELECT Ord,Val,Ind=DENSE_RANK()OVER(ORDER BY M) FROM
(
SELECT M=MIN(Ord)OVER(PARTITION BY N,Val),* FROM
(
SELECT N=ROW_NUMBER()OVER(ORDER BY Ord)-ROW_NUMBER()OVER(PARTITION BY Val ORDER BY Ord),*
FROM T
)T
)T
ORDER BY Ord;


да, интересно придумано!
и на больших данных работает быстро!
8 май 13, 15:02    [14274179]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить