powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Первая следующая "не такая". Можно ли решить с помощью оконных функций?
9 сообщений из 9, страница 1 из 1
Первая следующая "не такая". Можно ли решить с помощью оконных функций?
    #39943191
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Коллеги, приветствую!

Уже часа 2 активно туплю.
Можно ли решить "в один проход", с помощью оконной функции, следующую задачу:
Нужно каждому [i], сопоставить следующий в порядке возрастания [k] [i], в том случае если у этого следующего [i] ---- [j] > 0

Неправильный вариант решения - я привел:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Declare @t table (i int, j int, k int identity (1,1))

insert into @t (i,j)
Values (1, 1), (3, 1), (2, 1), (4, 0), (6, 1), (5, 0), (9, 0),  (7, 1), (8, 0), (10, 1), (11, 0)

Select i,
FIRST_VALUE(Case when j>0 then i  END) over (order by Case when j=0 then 1 Else 0 END ASC, k asc
Rows between 1 Following and Unbounded Following
) ii

from @t a
Order by k ASC


Он выдает:
i ii1 33 22 64 NULL6 75 NULL9 NULL7 108 NULL10 NULL11 NULL

А нужно:
i ii1 33 22 64 66 75 79 77 108 1010 NULL11 NULL

Обратите внимание, что никакое решение, кроме однопроходного оконного - мне не интересно.
Я легко могу решить этот кейс с помощью, например, самосоединения таблицы.
Интересует именно решение с помощью оконной функции!
...
Рейтинг: 0 / 0
Первая следующая "не такая". Можно ли решить с помощью оконных функций?
    #39943221
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
Select
 i,
 min(case when j > 0 then k * 1000 + i end) over (order by k rows between 1 following and unbounded following) % 1000
from @t a
Order by k ASC
...
Рейтинг: 0 / 0
Первая следующая "не такая". Можно ли решить с помощью оконных функций?
    #39943226
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm
Код: sql
1.
2.
3.
4.
5.
Select
 i,
 min(case when j > 0 then k * 1000 + i end) over (order by k rows between 1 following and unbounded following) % 1000
from @t a
Order by k ASC


Гыыы, какой грязный трюк! invm, спасибо.
В оригинале i - guid, но сейчас гляну, что можно сделать!
Спасибо. :-)
...
Рейтинг: 0 / 0
Первая следующая "не такая". Можно ли решить с помощью оконных функций?
    #39943241
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster
В оригинале i - guid
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Declare @t table (i int, j int, k int identity (1,1), g uniqueidentifier default newid())

insert into @t (i,j)
Values (1, 1), (3, 1), (2, 1), (4, 0), (6, 1), (5, 0), (9, 0),  (7, 1), (8, 0), (10, 1), (11, 0)

Select
 i, g,
 min(case when j > 0 then k * 1000 + i end) over (order by k rows between 1 following and unbounded following) % 1000,
 cast(substring(min(case when j > 0 then str(k, 10) + cast(g as varchar(36)) end) over (order by k rows between 1 following and unbounded following), 11, 100000) as uniqueidentifier)
from @t a
Order by k ASC
...
Рейтинг: 0 / 0
Первая следующая "не такая". Можно ли решить с помощью оконных функций?
    #39943275
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm, Да, спасибо, примерно так и сделал.
...
Рейтинг: 0 / 0
Первая следующая "не такая". Можно ли решить с помощью оконных функций?
    #39943341
nullin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
uaggster, как-то такое сделал без конкатенаций в несколько уровней оконок. Пишу, как любитель оконных функций

Кмк, в примере выше, stuff() был бы по изящнее, хотя насчет переносимости не уверен.
...
Рейтинг: 0 / 0
Первая следующая "не такая". Можно ли решить с помощью оконных функций?
    #39943346
nullin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
Declare @t table (i int, j int, k int identity (1,1), g uniqueidentifier default newid())

insert into @t (i,j)
Values (0, 0), (7, 0), (8, 1), (3, 1), (7, 1), (4, 0), (6, 1), (5, 0), (9, 0),  (5, 1), (8, 0), (10, 1), (11, 0), (0, 1)

select i, j, k, s
     , v
     , max(v) over(partition by s) as iRes
     , g
     , max(lg) over(partition by s) as gRes
from (select i, g, j, k
           , sum(j) over(order by k) as s
           , iif(1 = lead(j) over(order by k), lead(i) over(order by k), null) as v
           , iif(1 = lead(j) over(order by k), lead(g) over(order by k), null) as lg
      from @t a) as b


fiddle
...
Рейтинг: 0 / 0
Первая следующая "не такая". Можно ли решить с помощью оконных функций?
    #39943385
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
nullin, Блин, это даже не раскуришь с наскока.
Нет, запрос invm мне больше нравится (на первый взгляд). Реальный запрос на реальной базе на 15 миллионах записей считался всего около 10 минут. И да, со stuff. Присобачиваю спереди значение поля, по которому производится сортировка (datatime), а потом усекаю как stuff(..., 1, 19, '')
...
Рейтинг: 0 / 0
Первая следующая "не такая". Можно ли решить с помощью оконных функций?
    #39943500
nullin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
uaggster, план этого запроса по сравнению с запросом от invm может ужаснуть
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Первая следующая "не такая". Можно ли решить с помощью оконных функций?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]