Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Удаление зеркальных дубликатов  [new]
RemoteDuplicate
Guest
Доброго всем дня!
Понимаю что пятница и хочется отдохнуть, но не подскажите один вопросик. Как исключить зеркальные дубли?
Например:
Дано
select * from
(
	 select 1 as a, 2 as b union all
	 select 3 as a, 4 as b union all
	 select 2 as a, 1 as b union all
	 select 4 as a, 3 as b
)t

этот запрос выдает
a           b
----------- -----------
1 2
3 4
2 1
4 3
А мне надо получить
a           b
----------- -----------
1 2
3 4

Само собой таких вариантов куча и они могут идти не подряд. Версия сервера от 2005 и выше.
16 дек 11, 10:40    [11776119]     Ответить | Цитировать Сообщить модератору
 Re: Удаление зеркальных дубликатов  [new]
AHDP
Member

Откуда:
Сообщений: 1226
Select a, b from c
Union
Select b, a from c
16 дек 11, 10:57    [11776218]     Ответить | Цитировать Сообщить модератору
 Re: Удаление зеркальных дубликатов  [new]
grigrim
Member

Откуда: Москва
Сообщений: 89
RemoteDuplicate,

select a, b
from
(	select a, b, row_number() over(partition by a2, b2 order by a, b) num
	from
	(	select a, b, case when a<b then a else b end a2,
			case when a<b then b else a end b2
		from
		(	 select 1 as a, 2 as b union all
			 select 3 as a, 4 as b union all
			 select 2 as a, 1 as b union all
			 select 4 as a, 3 as b
		) t
	) t
) t
where num > 1
16 дек 11, 10:58    [11776224]     Ответить | Цитировать Сообщить модератору
 Re: Удаление зеркальных дубликатов  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
AHDP
Select a, b from c
Union
Select b, a from c
with t(a,b) as
(
	 select 0, 5 union all
	 select 1, 2 union all
	 select 3, 4 union all
	 select 2, 1 union all
	 select 4, 3
)
select a,b from t
union
select b,a from t;
Откуда взялась запись (a=5, b=0)?
16 дек 11, 11:05    [11776286]     Ответить | Цитировать Сообщить модератору
 Re: Удаление зеркальных дубликатов  [new]
AHDP
Member

Откуда:
Сообщений: 1226
AHDP
Select a, b from c
Union
Select b, a from c


Упс, сразу не въехал

Select c1.a, c1.b
from c c1 left join c c2 on c1.a = c2.b and c1.b = c2.a
where c2.a is null
16 дек 11, 11:09    [11776324]     Ответить | Цитировать Сообщить модератору
 Re: Удаление зеркальных дубликатов  [new]
_ч_
Member

Откуда:
Сообщений: 1446
grigrim
RemoteDuplicate,

select a, b
from
(	select a, b, row_number() over(partition by a2, b2 order by a, b) num
	from
	(	select a, b, case when a<b then a else b end a2,
			case when a<b then b else a end b2
		from
		(	 select 1 as a, 2 as b union all
			 select 3 as a, 4 as b union all
			 select 2 as a, 1 as b union all
			 select 4 as a, 3 as b
		) t
	) t
) t
where num > 1


Я бы написал where num = 1, т.к. если данные будут например такими:

			 select 0 as a, 5 as b union all
			 select 1 as a, 2 as b union all
			 select 3 as a, 4 as b union all
			 select 2 as a, 1 as b union all
			 select 4 as a, 3 as b


то запрос не вернет строку (0,5)
16 дек 11, 11:10    [11776332]     Ответить | Цитировать Сообщить модератору
 Re: Удаление зеркальных дубликатов  [new]
RemoteDuplicate
Guest
grigrim
RemoteDuplicate,

select a, b
from
(	select a, b, row_number() over(partition by a2, b2 order by a, b) num
	from
	(	select a, b, case when a<b then a else b end a2,
			case when a<b then b else a end b2
		from
		(	 select 1 as a, 2 as b union all
			 select 3 as a, 4 as b union all
			 select 2 as a, 1 as b union all
			 select 4 as a, 3 as b
		) t
	) t
) t
where num > 1

Спасиб, тебе мил человек. А подскажите Ваш код будет работать, вот эта часть
 when a<b then a else b end a2,
			case when a<b then b else a end b2

если скажем a и b будет varchar, datetime или Guid ? с циферками я так, для простаты привела.
16 дек 11, 11:12    [11776357]     Ответить | Цитировать Сообщить модератору
 Re: Удаление зеркальных дубликатов  [new]
grigrim
Member

Откуда: Москва
Сообщений: 89
RemoteDuplicate,

главное, чтобы a и b были одного типа.
16 дек 11, 11:18    [11776371]     Ответить | Цитировать Сообщить модератору
 Re: Удаление зеркальных дубликатов  [new]
AHDP
Member

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

Так она должна быть (нет пары), а мой первый вариант вернёт всю таблицу целиком. :(
16 дек 11, 11:18    [11776375]     Ответить | Цитировать Сообщить модератору
 Re: Удаление зеркальных дубликатов  [new]
RemoteDuplicate
Guest
grigrim
RemoteDuplicate,

главное, чтобы a и b были одного типа.


Спасибо вам огромное. Вы меня спасли. Буду разбираться(изучать) с вашим примером.

_ч_
Я бы написал where num = 1, т.к. если данные будут например такими

да с 1-кой он возвращает первые значения, и те для которых нет пары. Но таких значений (одиночек, нет пары) в наборе данных не существуют. Есть как минимум одна пара.

з.ы. тема закрыта. Всем участникам спасибо за помощь.
16 дек 11, 11:33    [11776463]     Ответить | Цитировать Сообщить модератору
 Re: Удаление зеркальных дубликатов  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
AHDP
iap,

Так она должна быть (нет пары), а мой первый вариант вернёт всю таблицу целиком. :(
Как это - должна?!

Из первоначального набора строк надо было УДАЛИТЬ дубликаты.
А в Вашем примере ДОБАВИЛАСЬ запись, которой первоначально не было,
причём из-за этого появился новый дубликат (вот так удалили, как говорится!)

Наличие дубликата для любой записи не гарантировалось по условию задачи.
16 дек 11, 12:00    [11776668]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить