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

Откуда: Київ
Сообщений: 10428
declare @t table(id int not null identity, group_id int, name nvarchar(128))
insert into @t(group_id, name)
select 1, N'name1'
union all
select 1, N'name2'
union all
select 1, N'name11'
union all
select 2, N'name1'
union all
select 2, N'name11'
union all
select 2, N'name2'
union all
select 3, N'name3'
union all
select 3, N'name4'
union all
select 4, N'name1'
union all
select 4, N'name2'
union all
select 4, N'name11'


Как получить группы что-то типа таких в даннмо случае, предположим номер комбинации и записи

1 name1
1 name11
1 name2
2 name3
2 name4
11 июн 14, 18:21    [16156488]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать уникальные комибнации?  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4813
Winnipuh
declare @t table(id int not null identity, group_id int, name nvarchar(128))
insert into @t(group_id, name)
select 1, N'name1'
union all
select 1, N'name2'
union all
select 1, N'name11'
union all
select 2, N'name1'
union all
select 2, N'name11'
union all
select 2, N'name2'
union all
select 3, N'name3'
union all
select 3, N'name4'
union all
select 4, N'name1'
union all
select 4, N'name2'
union all
select 4, N'name11'


Как получить группы что-то типа таких в даннмо случае, предположим номер комбинации и записи

1 name1
1 name11
1 name2
2 name3
2 name4


SELECT DISTINCT group_id, name FROM @t
чем-то не устраивает
11 июн 14, 18:31    [16156522]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать уникальные комибнации?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
автор
SELECT DISTINCT group_id, name FROM @t
чем-то не устраивает?



а тем, что мне нужны уникальные комбинации имен по группам, здесь 1 и 2 - не номер группы, а чисто порядковый номер
И должно быть всего две комбинации


номер_комбинации запись
------------------- -------
1 name1
1 name11
1 name2

2 name3
2 name4


Переделал пример, чтобы не сбивал с толку ид группы

declare @t table(id int not null identity, group_id int, name nvarchar(128), combination_no int)
insert into @t(group_id, name)
select 100, N'name1'
union all
select 100, N'name2'
union all
select 100, N'name11'
union all
select 200, N'name1'
union all
select 200, N'name11'
union all
select 200, N'name2'
union all
select 300, N'name3'
union all
select 300, N'name4'
union all
select 400, N'name1'
union all
select 400, N'name2'
union all
select 400, N'name11'



По идее хотелось бы сделать так: определить и проставить в поле combination_no - номер уникальной комбинации

И результат по идее должен бы выглядеть так (4 колонка):

select * from @t
-----------------------
1	1	name1     1
2	1	name2     1
3	1	name11    1
4	2	name1     1
5	2	name11    1
6	2	name2      1
7	3	name3      2
8	3	name4      2
9	4	name1      1
10	4	name2      1
11	4	name11    1
11 июн 14, 18:48    [16156564]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать уникальные комибнации?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
исправление:

И результат по идее должен бы выглядеть так (4 колонка):

select * from @t
-----------------------
1 100 name1 1
2 100 name2 1
3 100 name11 1
4 200 name1 1
5 200 name11 1
6 200 name2 1
7 300 name3 2
8 300 name4 2
9 400 name1 1
10 400 name2 1
11 400 name11 1
11 июн 14, 18:49    [16156568]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать уникальные комибнации?  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4813
Winnipuh
исправление:

И результат по идее должен бы выглядеть так (4 колонка):

select * from @t
-----------------------
1 100 name1 1
2 100 name2 1
3 100 name11 1
4 200 name1 1
5 200 name11 1
6 200 name2 1
7 300 name3 2
8 300 name4 2
9 400 name1 1
10 400 name2 1
11 400 name11 1



В общем надо сначала сканкатенировать комбинации в строку name1-name2-name11 (иначе я не вижу способа повторять уникальность), потом всё становиться тривиально. Конкатенации через FOR XML подзапросом. Потом пробить DENSE_RANK(), чтобы получить номер уникальной комбинации. Сообразите, или вам надо расписать всё?

Подозреваю, что модет возникнуть проблема, если сканкатенированная строка слишком длянная
11 июн 14, 19:25    [16156662]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать уникальные комибнации?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
a_voronin
Winnipuh
исправление:

И результат по идее должен бы выглядеть так (4 колонка):

select * from @t
-----------------------
1 100 name1 1
2 100 name2 1
3 100 name11 1
4 200 name1 1
5 200 name11 1
6 200 name2 1
7 300 name3 2
8 300 name4 2
9 400 name1 1
10 400 name2 1
11 400 name11 1



В общем надо сначала сканкатенировать комбинации в строку name1-name2-name11 (иначе я не вижу способа повторять уникальность), потом всё становиться тривиально. Конкатенации через FOR XML подзапросом. Потом пробить DENSE_RANK(), чтобы получить номер уникальной комбинации. Сообразите, или вам надо расписать всё?

Подозреваю, что модет возникнуть проблема, если сканкатенированная строка слишком длянная


ага... еще сортировать надо, чтобы порядок не влиял.

Было бы интересно увидеть ваш вариант.
11 июн 14, 21:58    [16157109]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать уникальные комибнации?  [new]
zrb
Member

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

declare @t table(id int not null identity, group_id int, name nvarchar(128), combination_no int)
insert into @t(group_id, name)
select 100, N'name1'
union all
select 100, N'name2'
union all
select 100, N'name11'
union all
select 200, N'name1'
union all
select 200, N'name11'
union all
select 200, N'name2'
union all
select 300, N'name3'
union all
select 300, N'name4'
union all
select 400, N'name1'
union all
select 400, N'name2'
union all
select 400, N'name11'
;

select *
from @t
;

with cte as (
select distinct name
from @t
)

,cte2 as (
select c.name
	,group_id = (select top(1) group_id from @t where name = c.name)
from cte as c
)

,cte3 as (
select distinct group_id
	,nn = dense_rank() over (order by group_id)
from cte2
)

select t.*, c3.nn
from @t as t
inner join cte2 as c2
on c2.name = t.name
inner join cte3 as c3
on c3.group_id = c2.group_id
order by t.id
11 июн 14, 22:47    [16157252]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать уникальные комибнации?  [new]
invm
Member

Откуда: Москва
Сообщений: 9683
with x as
(
 select
  *, checksum_agg(checksum(name)) over (partition by group_id) as c
 from
  @t
)
select
 id, group_id, name, dense_rank() over (order by c) as combination_id
from
 x
order by
 id;
11 июн 14, 23:45    [16157480]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать уникальные комибнации?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
спасибо всем, работают запросы, то, что надо!
Еще проверю на таблице с 10 млн записей.
12 июн 14, 08:10    [16157971]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать уникальные комибнации?  [new]
invm
Member

Откуда: Москва
Сообщений: 9683
Winnipuh
работают запросы, то, что надо!
Осторожнее. Вариант zbr нерабочий, а мой ненадежен и приведен только в качестве примера.
12 июн 14, 10:15    [16158126]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать уникальные комибнации?  [new]
Glory
Member

Откуда:
Сообщений: 104751
Мммм, может так ?

select name, gr_id,  DENSE_RANK() OVER  (ORDER BY a.gr_id) AS Rank
from(
select name, min(group_id) gr_id from @t
group by name) as a
12 июн 14, 10:32    [16158146]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать уникальные комибнации?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
invm
Winnipuh
работают запросы, то, что надо!
Осторожнее. Вариант zbr нерабочий, а мой ненадежен и приведен только в качестве примера.



на этом примере оба сработали, а в чем ненадежность и неправильность? checksum?
12 июн 14, 12:59    [16158518]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать уникальные комибнации?  [new]
invm
Member

Откуда: Москва
Сообщений: 9683
Winnipuh
на этом примере оба сработали
Ну добавьте какую-нибудь строку в 100, 200 или 400
Winnipuh
а в чем ненадежность и неправильность? checksum?
Да, checksum.
12 июн 14, 14:27    [16158722]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать уникальные комибнации?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Glory
Мммм, может так ?

select name, gr_id,  DENSE_RANK() OVER  (ORDER BY a.gr_id) AS Rank
from(
select name, min(group_id) gr_id from @t
group by name) as a


работает, спасибо, попробую на большой таблице...
12 июн 14, 16:04    [16158922]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать уникальные комибнации?  [new]
user89
Member

Откуда:
Сообщений: 2083
Winnipuh
исправление:
И результат по идее должен бы выглядеть так (4 колонка):
select * from @t
-----------------------
1 100 name1 1
2 100 name2 1
3 100 name11 1
4 200 name1 1
5 200 name11 1
6 200 name2 1
7 300 name3 2
8 300 name4 2
9 400 name1 1
10 400 name2 1
11 400 name11 1
+ Простое решение. Но на group_id нужен индекс
declare @t table(id int not null identity, group_id int, name nvarchar(128))
insert into @t(group_id, name)
select 100, N'name1' union all select 100, N'name2' union all select 100, N'name11' union all select 200, N'name1' union all
select 200, N'name11' union all select 200, N'name2' union all select 300, N'name3' union all select 300, N'name4' union all
select 400, N'name1' union all select 400, N'name2' union all select 400, N'name11';

;with b as (
  select t1.group_id,
  (select ',' + isnull(name,'') from @t t2 where t2.group_id = t1.group_id order by name for xml path(''),type).value('text()[1]','Nvarchar(max)') [strName]
  from @t t1
  group by t1.group_id
)
select a.*, dense_rank() over(order by strName) [combination_no]
from @t a
left join b on a.group_id = b.group_id
order by a.id
14 июн 14, 21:36    [16163853]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить