기본 키에서 여러 행을 반환하는 조인에서 첫 번째 행을 선택하는 방법


15

이 질문과 관련이 있습니다. 여러 테이블을 조인하면 행이 중복됩니다.

가입 할 테이블이 두 개 있습니다. 그들은 열쇠를 공유합니다. 개인 테이블에는 기본 키당 하나의 이름이 있지만 전자 메일 테이블에는 personId 당 여러 전자 메일이 있습니다. 한 사람당 첫 번째 이메일 만 표시하고 싶습니다. 현재 여러 이메일이 있기 때문에 한 사람당 여러 행을 얻습니다. SQL-Server 2005를 실행 중입니다.

편집 : 이것은 T-SQL입니다. 첫 번째 이메일은 말 그대로 개인당 첫 번째 이메일 행입니다.

편집 2 : 내가 본 첫 번째 전자 메일은 SQL이 쿼리를 통해 작동 할 때 조인에 나타나는 첫 번째 전자 메일 행입니다. 어떤 이메일이 표시되는지는 중요하지 않습니다. 하나의 이메일 만 표시됩니다. 그것이 더 명확 해지기를 바랍니다.

Table1: Person
Table2: Email

Select Person.PersonName, Email.Email
From person 
left join on Person.ID=Email.PersonId;

3
"첫 번째"이메일은 무엇을 의미합니까? 어떤 정렬 기준이 "첫 번째"를 결정합니까?
대기열 Mann

1
당신은 최고 1을 시도 했습니까?
Racer SQL

3
어떤 DBMS를 사용하고 있습니까? Postgres? 신탁?
a_horse_with_no_name

3
"사람마다 첫 번째 이메일 행은" 정말 우리에게 아무것도 말하지 않습니다. 어떤 기준으로 "첫 번째"? SQL 테이블에는 고유 한 순서가 없습니다.
ypercubeᵀᴹ

5
글쎄, 그것은 하나의 유효한 기준입니다.
ypercubeᵀᴹ

답변:


18
SELECT
    A.PersonName, A.Email
FROM
        (
        Select Person.PersonName, Email.Email
            ,ROW_NUMBER() OVER(PARTITION BY Person.ID ORDER BY Email.Email) AS RN
        From person 
        left join Email on Person.ID=Email.PersonId
        ) A
WHERE A.RN = 1

1
'A'는 무엇입니까? 테이블 이름의 약어입니까?
normandantzig 2016 년

2
@normandantzig 별명 입니다.
베이컨 비트

1
1.) 보낸 사람 (Person.PersonName, Email.Email, ROW_NUMBER () OVER (PARTITION BY Person.ID ORDER BY Email.Email)을 사용하여 내 테이블을 모두 별칭으로 지정 했습니까? A.를 테이블로 사용하여 두 열을 모두 참조 할 수 있도록 Email.PersonId) A And 2.)?
normandantzig 2016 년

4
괄호 안에있는 것을 파생 테이블 이라고 합니다 . 기본 테이블과 마찬가지로 유효한 테이블이지만 수명은 쿼리 실행 기간 동안 만 유효합니다. 이름 (또는 별명)이 있어야하고 @sabin은 이름을 선택했습니다 A. 이 테이블에는 3 개의 열 (PersonName, Email, RN)이 있으며 괄호 밖에 있으며 코드의 다른 모든 테이블에 A.Email사용할 수있는 것처럼 사용할 수 있습니다 tablename.columnname.
ypercubeᵀᴹ

13

나는 이것을 위해 외부 적용을 사용할 것입니다. 더 읽기 쉽습니다.

Select Person.PersonName, coalesce(Email.Email,'No email found.') as Email
From person 
outer apply (
  select top(1) Email.Email 
  from Email 
  where Person.ID=Email.PersonId
  order by <whatever suits you>
) as Email;

5

어떤 이메일이 표시되는지는 중요하지 않습니다. 다음은 매우 직접적이라고 생각합니다.

Select Person.PersonName,  MIN(Email.Email)
From person 
left join email 
on Person.ID=Email.PersonId
group by Person.Id, Person.PersonName

3
select
  P.PersonID,
  (SELECT TOP 1 E.Email FROM Email E WHERE E.PersonID = P.PersonID ORDER BY <pick your column here>)
from
  Person P

1
'P'란 무엇입니까? 테이블 이름의 약어입니까?
normandantzig 2016 년

1
'P'는 Person의 별명입니다. FROM 절의 테이블 선언을 따릅니다.
대기열 Mann

1
@normandantzig 둘 다 대부분의 상황에서 SQL Server에서 유효합니다.
베이컨 비트
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.