2017-03-29 2 views
1

이름, 성 및 전자 메일 주소가있는 연락처 목록이 있습니다. 일부 이메일 주소에는 성과 이름이 여러 개 있습니다. 저는 이메일 주소에 대해 더 염려합니다. 나는 그 이메일 주소의 최고 이름을 정말로 원한다.SQL Server 2014 - 고유 레코드를 찾는 방법

내 코드는 분명히 작동하지 않습니다

SELECT Salutation 
, FirstName 
, LastName 
, EmailAddress 
FROM Contact 
--GROUP BY EmailAddress ---I know a Group by will surely help 

내가이 일을

SELECT max(Salutation) 
    ,max(FirstName) 
    ,max(LastName) 
    ,max(EMailAddress) 
FROM Contact 
WHERE EMailAddress NOT LIKE '' 
GROUP BY EMailAddress 

시도했지만 그것을 할 수있는 더 좋은 방법이 있는지 궁금 해요.

+0

당신은 어떻게 정의합니까 ** 정상 ** 이름을? – SqlZim

+0

중복 된 이름 전체에 대해'max()'를 사용하면 이름이 다른 레코드를 얻을 수 있습니다. 예 : 'Aaron Bertrand'와 'Itzik Ben-Gan'이 당신에게 'Itzik Bertrand'를 줄 것입니다. 혼합 된 인사말을 가지고 있다면 항상 '부인'을 얻을 것입니다. 'Mr.' 및 '부인'. – SqlZim

답변

1

어떻게 정의합니까 이름이입니까?

이름에 max()을 사용하면 이름이 서로 다른 결과를 쉽게 반환 할 수 있습니다. 'Aaron Bertrand'와 'Itzik Ben-Gan'은 'Itzik Bertrand'를 반환합니다. Salutation을 섞은 경우 항상 '부인'을 얻을 수 있습니다. 'Mr.' '부인' 그것은 적절하지 않을지도 모른다.


top with tiesrow_number() 사용 :

select top 1 with ties 
    Salutation 
    , FirstName 
    , LastName 
    , EmailAddress 
from contact 
where EmailAddress <> '' 
order by row_number() over (
    partition by EmailAddress 
    order by FirstName /* your 'top' criteria here, FirstName is a placeholder */ 
); 

cross apply() 버전 :

;with cte as (
    select * 
    , rn = row_number() over (
      partition by EmailAddress 
       order by FirstName 
      ) 
    from contact 
    where EmailAddress <> '' 
) 
select 
    Salutation 
    , FirstName 
    , LastName 
    , EmailAddress 
from cte 
where rn = 1; 
:

select distinct 
    x.Salutation 
    , x.FirstName 
    , x.LastName 
    , t.EmailAddress 
from contact t 
    cross apply (
    select top 1 
     i.Salutation 
     , i.FirstName 
     , i.LastName 
    from t as i 
    where i.EmailAddress = t.EmailAddress 
    order by i.FirstName 
    ) as x 
where t.EmailAddress <> '' 

common table expression 버전과 row_number()

내가 공통 테이블 표현식을 사용하여 선호하지만, 그 안에 쿼리가 from 절에서와 마찬가지로 잘 작동 : 하위 쿼리 버전

row_number() :

select 
    Salutation 
    , FirstName 
    , LastName 
    , EmailAddress 
from (
    select * 
    , rn = row_number() over (
      partition by EmailAddress 
       order by FirstName 
      ) 
    from contact 
    where EmailAddress <> '' 
) s 
where rn = 1; 
+0

고맙습니다. 나는 당신의 첫 번째 코드를 시험해 보았다. – user1777929

+0

@ user1777929 도와 드리겠습니다! – SqlZim

0

시도 :

SELECT Salutation 
, FirstName 
, LastName 
, EmailAddress 
FROM Contact 
WHERE EmailAddress IS NULL 
     OR ID IN 
     (SELECT MAX(ID) 
     FROM Contact 
     WHERE EmailAddress IS NOT NULL 
     GROUP BY EmailAddress) 

이 당신에게 마지막을 줄 것이다 각 이메일 주소를 추가했다.

+0

테이블에 ID 열이 없습니다. 'msg 207, 수준 16, 상태 1, 줄 6 'ID '열 이름이 잘못되었습니다. ' – user1777929

+0

@ user1777929 ID 열이 실제로 명명 된 것을 나열하지 않은 채 "ID"b/c를 사용했습니다. 다른 이름을 가진 id 열이 있으면 그냥 사용하십시오. LastEdit DateTime 열이있는 경우이를 사용할 수도 있습니다. – JBrooks

+0

답장을 보내 주셔서 감사합니다. 확실히 도움이되었습니다. – user1777929