tpkpradeep Ответов: 4

Удаление дубликатов в таблице на основе двух столбцов


Below is my table

Name1	Name2	Distance
BG	CH	280
CH 	BG	280
CH 	HY	350
HY	CH	350
CH 	CBE	500

I want remove duplicates in it How can i do it?

In above table describes distance between two cities, name1 is city1 & name2 is City2

Urgent help and attention is required..,

Thanks in Advance

Sergey Alexandrovich Kryukov

Почему бы не предотвратить добавление дубликатов в первую очередь?
—СА

tpkpradeep

ну хороший вопрос.. :) клиенты разного типа.., :)

4 Ответов

Рейтинг:
2

OriginalGriff

Сложный...но это возможно. Вы можете посмотреть здесь: https://support.microsoft.com/en-us/kb/139444[^] - это объясняет процесс, но я бы, вероятно, создал SQL-функцию, которая взяла два имени и вернула составное имя, которое было упорядочено, поэтому BG, CH вернул то же значение, что и CH, BG. И я надеюсь, что у вас там есть идентификационная колонка, потому что она вам понадобится!


tpkpradeep

Я бы, вероятно, создал SQL-функцию, которая взяла эти два имени и вернула составное имя, которое было упорядочено, так что BG, CH вернул то же значение, что и CH, BG

Как я могу это сделать? Я пытался по-разному, но не смог..., помогите мне в этом..., пожалуйста

OriginalGriff

Вы знаете, как создать функцию SQL (в отличие от хранимой процедуры), не так ли?

tpkpradeep

привет OriginalGriff
как насчет этого?.

выберите dup1 по.ФИО1,dup1 по.вкладке tab1 dup1 по.р-н
от
(
выберите t.РК
от
(
Выберите t1.name1 tab1,t2.name1,dense_rank() over (order by t1.name1) as rk
Из #tmp_dup t1
внутреннее соединение #tmp_dup t2 на t1.name1 = t2.name2 и t1.name2 = t2.name1
И t1.Name1 NOT IN (выберите name2 из #tmp_dup, где name2=t1.name1 и name1 = t2.name2)
группа по t1.name1,t2.name1
) как Т
группа по т. РК
имея count(t.rk) = 1
) как ДУП
левое внешнее соединение
(
Выберите t1.name1 tab1,t2.name1,dense_rank() over (order by t1.name1) as rk,t1.dist
Из #tmp_dup t1
внутреннее соединение #tmp_dup t2 на t1.name1 = t2.name2 и t1.name2 = t2.name1
И t1.Name1 NOT IN (выберите name2 из #tmp_dup, где name2=t1.name1 и name1 = t2.name2)
группа по t1.name1,t2.name1,t1.dist
) как dup1 на ДУП.= dup1 по РК.РК

tpkpradeep

:) Я знаю..,

Я попробовал это сделать

с КТР как(
выберите name1,name2,
функции row_number() над
(
заказ по имя1,имя2
) как УНТ
от
#tmp_dup
группа по имя1,имя2
)


выберите t1.name1,t1.name2,t1.rk
от
(
выберите.ФИО1,а.ФИО2,также.как УНТ УНТ,
dense_rank() над (приказ.ФИО1) в РК
от КТР в
где существует(
выберите 1 из cte b, где a.name1 = b.name2 и a.name2 = b.name1)
) Т1
группа по t1.name1,t1.name2,t1.rk


я получил вывод, как показано ниже

имя1 имя2 РК
BG CH 1
CH BG 2
CH HY 2
HY CH 3

но я был поражен удалением значения 2

Рейтинг:
2

Member 14676000

удалить из таблицы 1 t1
Где t1.name1>t1.name2


CHill60

Итак, если бы 4 года назад у ОП была таблица, содержащая

Name1	Name2	Distance
BG	CH	280
CH 	BG	280
HY 	CH	350
CH 	CBE	500
Вы бы попросили их удалить строку HY + CH, несмотря на то, что она не дублируется.

Рейтинг:
2

Member 14676000

выбрать * из таблица1 где rowid В (выбрать Т1.идентификатор rowid из таблицы table1 Т1,Т2, где Т1 таблица1.Имя1&ГТ;Т1.ФИО2 и T1.Имя1=Т2.ФИО2 и T2.Имя1=Т1.ФИО2 );

удалить из таблицы 1, где rowid in (выберите t1.rowid из таблицы 1 t1,table1 t2, где t1.Name1>t1.Name2 и t1.Name1=t2.Name2 и t2.Name1=t1.Name2 );


CHill60

Вчера вы опубликовали решение. Не публикуйте несколько решений одного и того же вопроса - это сбивает с толку всех и просто выглядит как rep-point farming.
Это решение ничем не лучше вашего оригинала, но начинает выглядеть как копия решения 4.
Всегда читайте предыдущие решения и убедитесь, что вы привносите что-то новое в поток ... вряд ли после того, как прошло 4 года.

Member 14676000

Выше решение 4 не является копией решения 4,это улучшенное решение 4 ,они никогда не использовали концепцию rowid

Рейтинг:
1

Member 7870345

Решение состоит в том, чтобы в первую очередь точно определить, где находятся "плохие регистры". Если мы видим записи (BG, CH, 280) и (CH,BG,280), то проблемы состоят в том, что они "равны", если они были вставлены всегда в оба поля в алфавитном порядке, то есть (BG, CH,280). Таким образом, запись не очень хороша на первый взгляд, если name2 является
предшествующий имени 1.

Запрос:

SELECT 
	CASE WHEN t1.name1<>(CASE WHEN t1.name1<t1.name2 THEN t1.name1 ELSE t1.name2 end) THEN 'bad register' else 'good registerk' end as clase
	,t1.*
  FROM table1 t1

говорит, что (ч, БГ, 280), (хы,ч, 350) могут неправильно зарегистрировать' (что правильно), но также говорит, что (ч,све, 500) - это неправильно зарегистрировать' (что является неправильным).
Эта последняя запись действительно не является "неправильным регистром", потому что нет "зеркального" регистра (CBE, CH, 250)

Итак, если мы используем запрос:
SELECT 
	CASE WHEN t1.name1<>(CASE WHEN t1.name1<t1.name2 THEN t1.name1 ELSE t1.name2 end) THEN 'wrong register' else 'ok register' end as clase
	,t1.*
  FROM table1 t1
  JOIN table1 t2
  ON t1.name1=t2.name2 AND t1.name2=t2.name1

у нас есть только настоящий "неправильный регистр" (потому что если нет регистра "мирроу" , то он говорит, что это "ок-регистр")

Затем, запрос:
SELECT t1.*
  FROM table1 t1
  JOIN table1 t2
  ON t1.name1=t2.name2 AND t1.name2=t2.name1
  WHERE t1.name1<>(CASE WHEN t1.name1<t1.name2 THEN t1.name1 ELSE t1.name2 end) 


просто перечислите записи, которые вам нужно удалить.

или, проще говоря,:
SELECT t1.*
  FROM table1 t1
  JOIN table1 t2
  ON t1.name1=t2.name2 AND t1.name2=t2.name1
  WHERE t1.name1>t1.name2



Наконец то заказ:
delete TABLEdELETE
	FROM table1 tableDelete
	inner JOIN table1 t1
		on tabledelete.name1=t1.name1 and tabledelete.name2=t1.name2	
	inner JOIN  table1 t2
		ON ( t1.name1>t1.name2 AND t1.name1=t2.name2 AND t1.name2=t2.name1 ) 

удаляет нужный вам регистр.

Примечание: Если ваши данные являются:
BG CH 1
CH BG 2
CH HY 2
HY CH 3

и вы не хотите, чтобы запись CH, BG, 2 была удалена, а затем использована:
delete TABLEdELETE
	FROM table1 tableDelete
	inner JOIN table1 t1
		on tabledelete.name1=t1.name1 and tabledelete.name2=t1.name2 	
	inner JOIN  table1 t2
		ON ( t1.name1>t1.name2 AND t1.name1=t2.name2 AND t1.name2=t2.name1 AND t1.distance=t2.distance )