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

Откуда:
Сообщений: 1984
Добрый день!

Пусть есть таблица
declare @temp table(code int, ord int)
insert @temp(code,ord) values(1,1),(2,2),(3,3),(4,4),(2,5),(2,6)

select * from @temp
, где code - идентификатор элемента(fk), code - поле, которое задает сортировку.

Идем в порядке по полю ord, и если текущее значение code отличается от предыдущего, то увеличиваем номер группы.
Т.е. на выходе должны получить:
code	ord    group
1 1 1
2 2 2
3 3 3
4 4 4
2 5 5
2 6 5

Есть элегантное решение?
28 май 19, 10:55    [21895441]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
Щукина Анна
Member

Откуда:
Сообщений: 1431
__Avenger__
Есть элегантное решение?
Есть. И не одно. Искать на данном форуме по ключевому слову start_of_group, например...
28 май 19, 11:11    [21895466]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
Щукина Анна
Member

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

как вариант - поискать топики со словом " инвариант". Его не так прозрачно, как start_of_group, но можно и на вашу задачу натянуть...
28 май 19, 11:12    [21895470]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
BredSpit
Member

Откуда:
Сообщений: 19
>=2012 в лоб
declare @temp table(code int, ord int)
insert @temp(code,ord) values(1,1),(2,2),(3,3),(4,4),(2,5),(2,6)

;with cte 
as
(
select code,
case when  code<>lag(code)  over (order by ord)  and lag(code)  over (order by ord) is NOT NULL then 1 else 0 end as SM,ord
from @temp
)
select code,ord,sum(SM) over (order by ord)+1 
 from cte
28 май 19, 11:18    [21895477]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
Щукина Анна
Member

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

второй лаг - лишний. хватит и одного.
with t (code, ord)as 
(select * from (values(1,1),(2,2),(3,3),(4,4),(2,5),(2,6))v(c,o)
)
--
select code, ord
     , sum(start_of_group) over(order by ord) as x_dense_rank
  from (
         select code, ord
              , case lag(code) over(order by ord) 
                  when code then 0 
                  else 1 
                end as start_of_group 
           from t
       ) v
28 май 19, 11:22    [21895482]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
fkthat
Member

Откуда:
Сообщений: 1625
Элегантное решение - это не насиловть SQL, решая на нем совершенно нереляционные задачи, а делать такие вещи в клиентском приложении.
28 май 19, 11:32    [21895491]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
Щукина Анна
Member

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

разработчики так старались, засовывали в SQL оконные функции. Ицек БенГан написал толстую книгу по их использованию для написания эффективного SQL-кода. А вы так вот взяли и поставили на всем крест?
28 май 19, 11:34    [21895495]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
fkthat
Member

Откуда:
Сообщений: 1625
Щукина Анна
fkthat,

разработчики так старались, засовывали в SQL оконные функции. Ицек БенГан написал толстую книгу по их использованию для написания эффективного SQL-кода. А вы так вот взяли и поставили на всем крест?

Да зачем же крест ставить - прикольная штука. Особенно прикольно потом поддерживать такие запросы, где СTE, оконная ф-ия и вложенный подзапрос с еще одной оконной ф-ией. И это всего лишь в запросе, где даже десятка строк нет. А у нас тут есть, например, кое-какое легаси, где недавно нашли хранимку, в которой 2846 (две тысячи восемьсот сорок шесть - специально прописью повторил) строк
28 май 19, 11:45    [21895506]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
__Avenger__
Member

Откуда:
Сообщений: 1984
Спасибо. Все получилось.
28 май 19, 11:56    [21895523]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
Щукина Анна
Member

Откуда:
Сообщений: 1431
fkthat
А у нас тут есть, например, кое-какое легаси, где недавно нашли хранимку, в которой 2846 (две тысячи восемьсот сорок шесть - специально прописью повторил) строк
Вот именно потому в вашем легаси и есть 2846 строк (две тысячи восемьсот сорок шесть - специально прописью повторил(с)), что не было простых и надежный вариантов в виде "СTE, оконной ф-ия и вложенного подзапроса с еще одной оконной ф-ией"(с)
28 май 19, 12:00    [21895529]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
Щукина Анна
Member

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

перепишите хотелку автора без всего современного тюнинга. И получите очередное легаси, на сильно больше, чем 10 строк кода...
28 май 19, 12:01    [21895532]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
invm
Member

Откуда: Москва
Сообщений: 8852
Щукина Анна
fkthat,

перепишите хотелку автора без всего современного тюнинга. И получите очередное легаси, на сильно больше, чем 10 строк кода...
Зря стараетесь :)
Как показывает практика, подобные аргументы апологетами подхода "не насиловать SQL" не воспринимаются.
28 май 19, 12:22    [21895557]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
fkthat
Member

Откуда:
Сообщений: 1625
Щукина Анна
fkthat,

перепишите хотелку автора без всего современного тюнинга. И получите очередное легаси, на сильно больше, чем 10 строк кода...


Я бы, скорее всего, это поле group просто тупо вставлял еще при добавлении записей в таблицу.
28 май 19, 12:29    [21895567]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
Посетитель
Member

Откуда:
Сообщений: 1384
fkthat
нашли хранимку, в которой 2846 (две тысячи восемьсот сорок шесть - специально прописью повторил) строк Картинка с другого сайта.


а чего она такая маленькая то?
небось не форматировали, да каждый запрос в одну строку писали.
28 май 19, 12:38    [21895584]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
Щукина Анна
Member

Откуда:
Сообщений: 1431
fkthat
Я бы, скорее всего, это поле group просто тупо вставлял еще при добавлении записей в таблицу.
путь истинного джедая - хранить вычисляемые значения и изменять их всякий раз при обновлении данных в таблице... Хорошо, если данные будут прирастать только в "конец" таблицы. А если - в середину?

28 май 19, 12:41    [21895596]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
Wlr-l
Member

Откуда:
Сообщений: 505
fkthat
Элегантное решение - это не насиловть SQL, решая на нем совершенно нереляционные задачи, а делать такие вещи в клиентском приложении.



fkthat уверен, что сервер баз данных и приложение находятся в отношении 1:1.
28 май 19, 13:54    [21895689]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 6965
fkthat
Элегантное решение - это не насиловть SQL, решая на нем совершенно нереляционные задачи, а делать такие вещи в клиентском приложении.


Надо же понимать - где насилие. а где нет. Пробрасывать на клиента пару миллионов строк, чтобы рассчитать группы - самое прямое насилие, которое только есть. Нельзя спешить с выводами, не понимая контекста и не убедившись в правильности суждений в каждом конкретном случае.
28 май 19, 13:57    [21895697]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
fkthat
Member

Откуда:
Сообщений: 1625
Wlr-l,

Для тех, кто застрял в эпохе FoxPro и Дельфи, - под клиентским приложением подразумевается вовсе не обязательно окошко виндовс, в котором операционистка тетя Маша мышью тычет.
28 май 19, 13:59    [21895703]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
fkthat
Member

Откуда:
Сообщений: 1625
Владислав Колосов
Пробрасывать на клиента пару миллионов строк, чтобы рассчитать группы - самое прямое насилие, которое только есть.


Пробросить только нужные. По-любому, если их пронумеровать в сиквеле, как ТС хочет, то два млн. строк так и останутся двумя млн. строк, т.ч. наружу все равно отправится только какая-то их часть.
28 май 19, 14:06    [21895705]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
Wlr-l
Member

Откуда:
Сообщений: 505
fkthat
Wlr-l,

Для тех, кто застрял в эпохе FoxPro и Дельфи, - под клиентским приложением подразумевается вовсе не обязательно окошко виндовс, в котором операционистка тетя Маша мышью тычет.


О, да! У вас крутое приложение с запросами по тысячи строк SQL, в которых вам не разобраться, лучше на С да с for на клиенте!
А мы, что? глушь, деревня! С приложениями, реализованными с помощью Delphi, C#, Excel со его VBA, только FoxPro уже осталась в воспоминаниях. Да еще и наша тетя Маша мышью тычет куда попало!
28 май 19, 14:14    [21895718]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
Wlr-l
Member

Откуда:
Сообщений: 505
fkthat
Владислав Колосов
Пробрасывать на клиента пару миллионов строк, чтобы рассчитать группы - самое прямое насилие, которое только есть.


Пробросить только нужные. По-любому, если их пронумеровать в сиквеле, как ТС хочет, то два млн. строк так и останутся двумя млн. строк, т.ч. наружу все равно отправится только какая-то их часть.


АГА, если пронумеровать, то получить группы уже не так сложно. Книгу, где это описывается вам уже порекомендовали!

Так два миллиона строк на клиента вывалили, а теперь еще и с номерами!

Кстати, сиквел - неудачный термин. Историю надо знать!
28 май 19, 14:18    [21895722]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
fkthat
Member

Откуда:
Сообщений: 1625
Wlr-l,

Тебе бы из книг я порекомендовал начать с букваря. Глядишь, научился бы сначала читать, что тебе другие пишут.
28 май 19, 14:31    [21895743]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разбить на группы  [new]
invm
Member

Откуда: Москва
Сообщений: 8852
fkthat
Пробросить только нужные. По-любому, если их пронумеровать в сиквеле, как ТС хочет, то два млн. строк так и останутся двумя млн. строк, т.ч. наружу все равно отправится только какая-то их часть.
Вам бы матчасть по ранжирующим и оконным функциям подучить, а потом уже дискутировать.
28 май 19, 14:38    [21895759]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить