CHill60
Вот альтернатива решению 1, которому, как мне кажется, легче следовать. Я создал тестовые данные следующим образом:
create table #test
(id int identity(1,1),phone nvarchar(123),Email nvarchar(123),Person int)
insert into #test (phone, Email) values
('111', 'abc@gmail.com'),
('112', 'abc@gmail.com'),
('112', 'pqr@hotmail.com'),
('113', 'abc@gmail.com'),
('211', 'someoneelse@live.com')
Сначала используйте функцию SQL Window, чтобы дать нам предлагаемые номера "персон", основанные только на адресе электронной почты:
UPDATE T SET Person = D.RN FROM #test T
INNER JOIN
(SELECT id, DENSE_RANK() OVER (ORDER BY Email) AS RN FROM #test) D on D.id = T.ID
Это содержание #test после этого:
id Phone Email Person
1 111 abc@gmail.com 1
2 112 abc@gmail.com 1
3 112 pqr@hotmail.com 2
4 113 abc@gmail.com 1
5 211 someoneelse@live.com 3
Это следующее утверждение исправляет ситуацию для телефонного номера ... то есть оно заменит Person = 2 на Person = 1, потому что это один и тот же "человек". Мне доводилось пользоваться
MIN
чтобы получить более раннее
Person
номер но вы могли бы так же легко использовать
MAX
:
UPDATE T SET Person = newPerson
from (
SELECT PHONE, min(person) as newPerson FROM #test
GROUP BY phone having count(*) > 1) AS q
inner join #test t on q.phone=t.phone
Содержание #test после этого:
id Phone Email Person
1 111 abc@gmail.com 1
2 112 abc@gmail.com 1
3 112 pqr@hotmail.com 1
4 113 abc@gmail.com 1
5 211 someoneelse@live.com 3
Вы можете просто остановиться на этом, так как у каждого человека есть уникальное число (1 и 3), но если вы действительно хотите, чтобы числа были последовательными, то запустите эту последнюю часть. Это изменение каждого отдельного
Person
с помощью
RANK
но вы могли бы так же легко использовать
ROW_NUMBER()
UPDATE T SET Person = Q2.NP
FROM #test T
INNER JOIN (select Person, RANK() OVER (ORDER BY Person) AS NP FROM (select distinct Person from #test) Q1) Q2 ON Q2.Person=T.Person
Окончательные результаты таковы
id Phone Email Person
1 111 abc@gmail.com 1
2 112 abc@gmail.com 1
3 112 pqr@hotmail.com 1
4 113 abc@gmail.com 1
5 211 someoneelse@live.com 2
Вот полный код, выполненный в виде однострочных строк, чтобы он выглядел короче ;-)
create table #test (id int identity(1,1),phone nvarchar(123),Email nvarchar(123),Person int)
insert into #test (phone, Email) values
('111', 'abc@gmail.com'),
('112', 'abc@gmail.com'),
('112', 'pqr@hotmail.com'),
('113', 'abc@gmail.com'),
('211', 'someoneelse@live.com')
UPDATE T SET Person = D.RN FROM #test T INNER JOIN ( SELECT id, DENSE_RANK() OVER (ORDER BY Email) AS RN FROM #test) D on D.id = T.ID
UPDATE T SET Person = newPerson from (SELECT PHONE, min(person) as newPerson FROM #test GROUP BY phone having count(*) > 1) AS q inner join #test t on q.phone=t.phone
UPDATE T SET Person = Q2.NP FROM #test T INNER JOIN (select Person, ROW_NUMBER() OVER (ORDER BY Person) AS NP FROM (select distinct Person from #test) Q1) Q2 ON Q2.Person=T.Person
select * from #TEST
DROP TABLE #test