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

Откуда:
Сообщений: 438
Здравствуйте! Есть таблица с автоинкрементным полем примерно такого содержания:

idxNaimval
1c0
2a0
3a8
4a5
5b0
6b15
7b27
8a39
9a5
10a12

Надо получить
idxNaimval
1c0
4a5
6b15
7b27
10a12


Здесь для каждого "Naim" надо получить записи с максимальным "idx". Новая группа начинается, если "val" >= 20.

Тестовые данные:
declare @t table (idx int identity, Naim varchar(1), val int)

insert @t
 select 'c',0 union all select 'a', 0 union all select 'a',8 union all select 'a',5 union all
 select 'b',0 union all select 'b',15 union all select 'b',27 union all select 'a',39 union all
 select 'a',5 union all select 'a',12

select * from @t

select @@version
Microsoft SQL Server 2005 - 9.00.3042.00 (Intel X86) 
	Feb  9 2007 22:47:07 
	Copyright (c) 1988-2005 Microsoft Corporation
	Developer Edition on Windows NT 5.2 (Build 3790: Service Pack 2)
25 июл 11, 11:42    [11021793]     Ответить | Цитировать Сообщить модератору
 Re: Запрос. Нестандартная группировка.  [new]
kDnZP
Member [заблокирован]

Откуда: ★[msg=16399436]★[msg=20850760]
Сообщений: 11289
Начинающий SQL 2008,
idxNaimval
8a39

А чего то, что выше в выборку не попадает.
ЗЫ: Архитектору большой привет передавайте))).
25 июл 11, 13:29    [11022674]     Ответить | Цитировать Сообщить модератору
 Re: Запрос. Нестандартная группировка.  [new]
stimpi
Member

Откуда: Киев, Украина
Сообщений: 662
select t.*
from @t t
  join (select MAX(idx) idx from @t
        group by naim, val / 20) tt on t.idx = tt.idx
order by t.idx

куда вы дели
idx Naim val
8a39
25 июл 11, 13:33    [11022706]     Ответить | Цитировать Сообщить модератору
 Re: Запрос. Нестандартная группировка.  [new]
Начинающий SQL 2008
Member

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

А там, где val >= 20, начало новой группы.

Т.е. если бы удалось получить что-то в в виде такого:
idxNaimvalgr
1c01
2a01
3a81
4a51
5b01
6b151
7b272
8a392
9a52
10a122

То запрос элементарный
declare @t table (idx int identity, Naim varchar(1), val int, gr int)

insert @t
 select 'c',0,1 union all select 'a', 0,1 union all select 'a',8,1 union all select 'a',5,1 union all
 select 'b',0,1 union all select 'b',15,1 union all select 'b',27,2 union all select 'a',39,2 union all
 select 'a',5,2 union all select 'a',12,2

select top 1 with ties *
from @t
order by row_number() over (partition by Naim,gr order by idx desc)

Проблема в том, чтобы правильно задать номер группы.
25 июл 11, 13:38    [11022759]     Ответить | Цитировать Сообщить модератору
 Re: Запрос. Нестандартная группировка.  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Начинающий SQL 2008,

вот такое правильно отрабатывает?
SET NOCOUNT ON;

DECLARE @T TABLE(idx INT, Naim CHAR, val INT);
INSERT @T(idx, Naim,val)VALUES
 (1, 'c', 0)
,(2, 'a', 0)
,(3, 'a', 8)
,(4, 'a', 5)
,(5, 'b', 0)
,(6, 'b', 15)
,(7, 'b', 27)
,(8, 'a', 39)
,(9, 'a', 5)
,(10, 'a', 12);

SELECT TOP(1) WITH TIES *
FROM @T
ORDER BY ROW_NUMBER()OVER(PARTITION BY Naim, CASE WHEN val<20 THEN 0 END ORDER BY idx DESC);
А казалось бы, все условия выполнены.
25 июл 11, 13:42    [11022785]     Ответить | Цитировать Сообщить модератору
 Re: Запрос. Нестандартная группировка.  [new]
Начинающий SQL 2008
Member

Откуда:
Сообщений: 438
iap,
не совсем.

Здесь, где Naim = "a" и val = 39 - это начало новой группы.
Двигаемся дальше, пока не найдем новый "Naim" c "val" >= 20 (или таблица не закончится).
И вот эту строку, которая перед "Naim" c "val" >= 20 и надо оставить
25 июл 11, 13:50    [11022844]     Ответить | Цитировать Сообщить модератору
 Re: Запрос. Нестандартная группировка.  [new]
Начинающий SQL 2008
Member

Откуда:
Сообщений: 438
т.е. получить номер группы, примерно как постом выше
11022759
25 июл 11, 13:53    [11022875]     Ответить | Цитировать Сообщить модератору
 Re: Запрос. Нестандартная группировка.  [new]
Начинающий SQL 2008
Member

Откуда:
Сообщений: 438
Вот накатал, но думаю, что это не очень эффективное решение...

;with cte1 as (
 select
 t.*, (select count(*) from @t t2 where t2.idx <= t.idx and t2.val >= 20) + 1 [gr]
 from @t t
),
cte2 as (
select cte1.*, row_number() over (partition by Naim,gr order by idx desc) [rn]
from cte1
)
select * from cte2
where rn = 1
order by idx -- необязательно, так, для проверки
25 июл 11, 14:15    [11023032]     Ответить | Цитировать Сообщить модератору
 Re: Запрос. Нестандартная группировка.  [new]
Начинающий SQL 2008
Member

Откуда:
Сообщений: 438
Так точнее:
;with cte as (
 select
 t.*, (select count(*) from @t t2 where t2.Naim = t.Naim and t2.idx <= t.idx and t2.val >= 20) + 1 [gr]
 from @t t
)
select top 1 with ties *
from cte
order by row_number() over (partition by Naim,gr order by idx desc)

Но получить номер группы, кроме как
(select count(*) from @t t2 where t2.Naim = t.Naim and t2.idx <= t.idx and t2.val >= 20) + 1 [gr]
не получилось Картинка с другого сайта.
25 июл 11, 14:19    [11023063]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить