SQL.RU
 client/server technologies
 
 Главная | Документация | Статьи | Книги | Форум | Опросы | Рассылка | Работа | Поиск | FAQ |

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

Откуда:
Сообщений: 176
Мне необходимо пронумеровать строки так, чтобы номер возрастал при смене поля ААА (см. пример)
Было (поля N, ААА)
1 "ааа"
2 "ббб"
3 "ввв"
4 "ввв"
5 "ббб"
6 "ббб"
7 "ббб"
8 "ааа"
Стало:
1 "ааа"
2 "ббб"
3 "ввв"
3 "ввв"
4 "ббб"
4 "ббб"
4 "ббб"
5 "ааа"
Как это сделать?
30 июл 10, 14:45    [9185058] Ответить | Цитировать    Сообщить модератору

 Re: Помогите с запросом   [new]
AmKad
Member

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

with s as(
select 1 id, 'ааа' st union all
select 2 id, 'ббб' st union all
select 3 id, 'ввв' st union all
select 4 id, 'ввв' st union all
select 5 id, 'ббб' st union all
select 6 id, 'ббб' st union all
select 7 id, 'ббб' st union all
select 8 id, 'ааа' st --union all
)
select id, st, dense_rank() over (order by rn) new_id
from
   (select id, st,
	row_number() over (order by id) - row_number() over (partition by st order by id) rn
	from s
   ) s

id st new_id
1 ааа 1
2 ббб 2
3 ввв 3
4 ввв 3
5 ббб 4
6 ббб 4
7 ббб 4
8 ааа 5
30 июл 10, 15:05    [9185289] Ответить | Цитировать    Сообщить модератору

 Re: Помогите с запросом   [new]
ktybdsqgtym
Guest
select * into #t1 from 
(
select '1' [F1],'ааа' [F2] UNION ALL 
select '2','ббб' UNION ALL 
select '3','ввв' UNION ALL 
select '4','ввв' UNION ALL 
select '5','ббб' UNION ALL 
select '6','ббб' UNION ALL 
select '7','ббб' UNION ALL 
select '8','ааа'
) t1
alter table #t1 add res int

для 2000го. кстати можно ли без переменной?
declare @res int 
set @res=0

update t1 set @res=res=case when (select t2.F2 from #t1 t2 where t2.F1=t1.F1-1) = t1.F2 then @res else @res+1 end
from #t1 t1
select res,F2 from #t1
30 июл 10, 16:20    [9185924] Ответить | Цитировать    Сообщить модератору

 Re: Помогите с запросом   [new]
AmKad
Member

Откуда:
Сообщений: 899
AmKad
gigadedushka,

with s as(
select 1 id, 'ааа' st union all
select 2 id, 'ббб' st union all
select 3 id, 'ввв' st union all
select 4 id, 'ввв' st union all
select 5 id, 'ббб' st union all
select 6 id, 'ббб' st union all
select 7 id, 'ббб' st union all
select 8 id, 'ааа' st --union all
)
select id, st, dense_rank() over (order by rn) new_id
from
   (select id, st,
	row_number() over (order by id) - row_number() over (partition by st order by id) rn
	from s
   ) s

id st new_id
1 ааа 1
2 ббб 2
3 ввв 3
4 ввв 3
5 ббб 4
6 ббб 4
7 ббб 4
8 ааа 5

Приведенное решение неверно, т.к. дает некорректный результат на этих данных
with s as
(
select 1 id, 'aaa' st union all
select 3 id, 'bbb' name union all
select 4 id, 'bbb' name union all
select 5 id, 'bbb' name union all
select 6 id, 'ccc' name union all
select 7 id, 'ccc' name union all
select 8 id, 'ccc' name union all
select 15 id, 'aaa' name union all
select 16 id, 'aaa' name union all
select 18 id, 'bbb' name
)
select id, st, dense_rank() over (order by rn) new_id
from
   (select id, st,
	row_number() over (order by id) - row_number() over (partition by st order by id) rn
	from s
   ) s
id st new_id
1 aaa 1
3 bbb 2
4 bbb 2
5 bbb 2
6 ccc 3
7 ccc 3
8 ccc 3
15 aaa 4
16 aaa 4
18 bbb 4
30 июл 10, 18:29    [9186765] Ответить | Цитировать    Сообщить модератору

 Re: Помогите с запросом   [new]
AmKad
Member

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

Допилил напильником
with s as
(select 1 id, 'aaa' st union all
select 3 id, 'bbb' name union all
select 4 id, 'bbb' name union all
select 5 id, 'bbb' name union all
select 6 id, 'ccc' name union all
select 7 id, 'ccc' name union all
select 8 id, 'ccc' name union all
select 15 id, 'aaa' name union all
select 16 id, 'aaa' name union all
select 18 id, 'bbb' name
)

select s.id, s.st, dense_rank() over (order by s.id - s.dr) new_id
from
   (select s.id, s.st, 
    row_number() over (partition by s.new_id, s.st order by id) dr
    from
       (select 
        s.id, 
        s.st, 
        dense_rank() over (order by s.rn_global - rn_local) new_id
        from
           (select s1.id, s1.st,
            row_number() over (order by id) rn_global,
            row_number() over (partition by st order by id)rn_local
            from s s1
           ) s
        ) s  
   )s
id st new_id
1 aaa 1
3 bbb 2
4 bbb 2
5 bbb 2
6 ccc 3
7 ccc 3
8 ccc 3
15 aaa 4
16 aaa 4
18 bbb 5
30 июл 10, 18:43    [9186810] Ответить | Цитировать    Сообщить модератору

 Re: Помогите с запросом   [new]
AmKad
Member

Откуда:
Сообщений: 899
AmKad
gigadedushka,

Допилил напильником
with s as
(select 1 id, 'aaa' st union all
select 3 id, 'bbb' name union all
select 4 id, 'bbb' name union all
select 5 id, 'bbb' name union all
select 6 id, 'ccc' name union all
select 7 id, 'ccc' name union all
select 8 id, 'ccc' name union all
select 15 id, 'aaa' name union all
select 16 id, 'aaa' name union all
select 18 id, 'bbb' name
)

select s.id, s.st, dense_rank() over (order by s.id - s.dr) new_id
from
   (select s.id, s.st, 
    row_number() over (partition by s.new_id, s.st order by id) dr
    from
       (select 
        s.id, 
        s.st, 
        dense_rank() over (order by s.rn_global - rn_local) new_id
        from
           (select s1.id, s1.st,
            row_number() over (order by id) rn_global,
            row_number() over (partition by st order by id)rn_local
            from s s1
           ) s
        ) s  
   )s
id st new_id
1 aaa 1
3 bbb 2
4 bbb 2
5 bbb 2
6 ccc 3
7 ccc 3
8 ccc 3
15 aaa 4
16 aaa 4
18 bbb 5

with s as
(select 1 id, 'aaa' st union all
select 3 id, 'bbb' name union all
select 4 id, 'bbb' name union all
select 5 id, 'bbb' name union all
select 6 id, 'ccc' name union all
select 7 id, 'ccc' name union all
select 8 id, 'ccc' name union all
select 15 id, 'aaa' name union all
select 16 id, 'aaa' name union all
select 18 id, 'bbb' name
)

select s.id, s.st, dense_rank() over (order by s.rn_global - s.dr) new_id
from
   (select s.id, s.st, s.rn_global,
    row_number() over (partition by s.new_id, s.st order by id) dr
    from
       (select 
        s.id, 
        s.st, 
		s.rn_global,
        dense_rank() over (order by s.rn_global - rn_local) new_id
        from
           (select s1.id, s1.st,
            row_number() over (order by id) rn_global,
            row_number() over (partition by st order by id)rn_local
            from s s1
           ) s
        ) s  
   )s
30 июл 10, 18:46    [9186821] Ответить | Цитировать    Сообщить модератору

 Re: Помогите с запросом   [new]
Crimean
Member

Откуда:
Сообщений: 10366
по-моему как-то так эффективнее будет:

declare @a table( id int, name varchar(10) )

insert into @a
select 1 id, 'aaa' st union all
select 3 id, 'bbb' name union all
select 4 id, 'bbb' name union all
select 5 id, 'bbb' name union all
select 6 id, 'ccc' name union all
select 7 id, 'ccc' name union all
select 8 id, 'ccc' name union all
select 15 id, 'aaa' name union all
select 16 id, 'aaa' name union all
select 18 id, 'bbb' name

select * from @a;

with aaa as
(
select distinct name from @a
),
bbb as
(
select name, row_number() over ( order by name ) as no from aaa
)
select a.* , b.no from @a a join bbb b on b.name = a.name

все равно надо делать справочник имен, а это скан исходной таблицы. хорошо бы этот скан делать всего один раз
30 июл 10, 18:58    [9186861] Ответить | Цитировать    Сообщить модератору

 Re: Помогите с запросом   [new]
AmKad
Member

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

Ваш запрос дает не тот рез-тат, который хотел автор.
30 июл 10, 19:06    [9186884] Ответить | Цитировать    Сообщить модератору

 Re: Помогите с запросом   [new]
Crimean
Member

Откуда:
Сообщений: 10366
AmKad
Crimean,

Ваш запрос дает не тот рез-тат, который хотел автор.


увидел, спасибо. если я правильно понял, корректная постановка задачи - пронумеровать список в порядке возрастания первого поля таким образом, чтобы номер увеличивался при каждой смене значения второго поля. если так, то эффективного решения не видно, как по мне - дешевле всего сделать через FOR INSERT триггер (если не требуется реакция на изменения / удаления)
30 июл 10, 19:30    [9186958] Ответить | Цитировать    Сообщить модератору

 Re: Помогите с запросом   [new]
ChA
Member

Откуда: Москва
Сообщений: 6841
Еще вариант, может и не очень эффективный, но работает под MS SQL 2000
declare @a table( id int, name varchar(10) )

insert into @a
-- select 1, 'ааа'
-- union all select 2, 'ббб'
-- union all select 3, 'ввв'
-- union all select 4, 'ввв'
-- union all select 5, 'ббб'
-- union all select 6, 'ббб'
-- union all select 7, 'ббб'
-- union all select 8, 'ааа'
select 1 id, 'aaa' st union all
select 3 id, 'bbb' name union all
select 4 id, 'bbb' name union all
select 5 id, 'bbb' name union all
select 6 id, 'ccc' name union all
select 7 id, 'ccc' name union all
select 8 id, 'ccc' name union all
select 15 id, 'aaa' name union all
select 16 id, 'aaa' name union all
select 18 id, 'bbb' name

SELECT
	a0.name
	, COUNT(DISTINCT t.fig) + 1
FROM @a a0
LEFT JOIN (
	SELECT
		a1.id
		, (
			SELECT TOP 1 a2.id
			FROM @a a2
			WHERE
				a2.id < a1.id
				AND a2.name <> a1.name
			ORDER BY a2.id DESC
		) fig
	FROM @a a1
) t ON (t.id <= a0.id)
GROUP BY a0.ID, a0.name
ORDER BY a0.ID
Если ещё подумать, то наверняка можно улучшить.
30 июл 10, 23:55    [9187450] Ответить | Цитировать    Сообщить модератору

Все форумы / Microsoft SQL Server Ответить
Generated time: 93ms.
Rambler's Top100 Powered by ActualForum 1.5.3 [s1] Copyright (c) Alex Sibilev 2000-2010