Cách chọn hàng đầu tiên từ một phép nối trả về nhiều hàng trên khóa chính


14

Điều này có liên quan đến câu hỏi này: Tham gia nhiều bảng dẫn đến các hàng trùng lặp

Tôi có hai bảng mà tôi đang tham gia. Họ chia sẻ một chìa khóa. Bảng người có một tên cho mỗi khóa chính nhưng bảng email có nhiều email cho mỗi người. Tôi muốn chỉ hiển thị email đầu tiên cho mỗi người. Hiện tại tôi nhận được nhiều hàng cho mỗi người vì họ có nhiều email. Tôi đang chạy SQL-Server 2005.

EDIT: Đây là T-SQL. Email đầu tiên theo nghĩa đen là hàng email đầu tiên cho mỗi người.

Chỉnh sửa 2: Email đầu tiên mà tôi thấy nó sẽ là hàng email đầu tiên xuất hiện trong phép nối khi SQL hoạt động thông qua truy vấn. Tôi không quan trọng email nào xuất hiện. Chỉ có điều không có nhiều hơn một email xuất hiện. Tôi hy vọng điều đó làm cho nó rõ ràng hơn.

Table1: Person
Table2: Email

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

3
Bạn có ý nghĩa gì qua email "đầu tiên"? Những tiêu chí sắp xếp nào xác định "đầu tiên"?
Queue Mann

1
bạn đã thử top 1 chưa?
Racer SQL

3
DBMS nào bạn đang sử dụng? Hậu duệ? Oracle?
a_horse_with_no_name

3
Các "hàng email đầu tiên mỗi người" không thực sự cho chúng tôi bất cứ điều gì. "Đầu tiên" theo tiêu chí nào? Các bảng SQL không có thứ tự vốn có.
ypercubeᵀᴹ

5
Chà, đó là một tiêu chí hợp lệ: "Tôi không quan tâm hàng nào, chỉ một hàng".
ypercubeᵀᴹ

Câu trả lời:


17
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' là gì? Có phải là viết tắt của tên bảng?
Normandantzig

2
@normandantzig Đó là bí danh .
Bacon Bits

1
1.) Bạn có bí danh cả hai bảng của tôi bằng cách sử dụng Từ (Chọn Person.PersonName, Email.Email, ROW_NUMBER () QUÁ (THAM GIA B PersonNG CÁCH Email.PersonId) A và 2.) để bạn có thể tham khảo cả hai cột sử dụng A làm bảng?
Normandantzig

4
Những gì bên trong dấu ngoặc đơn được gọi là bảng dẫn xuất . Đó là một bảng hợp lệ, giống như các bảng cơ sở nhưng thời gian tồn tại của nó chỉ dành cho thời gian thực hiện truy vấn. Nó phải có tên (hoặc bí danh) và @sabin chọn đặt tên cho nó A. Bảng này có 3 cột (PersonName, Email, RN) và bên ngoài dấu ngoặc đơn, bạn có thể sử dụng A.Emailgiống như bạn có thể sử dụng tablename.columnnamecho mọi bảng khác trong mã của mình.
ypercubeᵀᴹ

13

Tôi sẽ sử dụng một ứng dụng bên ngoài cho điều này, tôi thấy nó dễ đọc hơn.

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

Vì nó không quan trọng mà email xuất hiện. Tôi nghĩ rằng sau đây là rất trực tiếp.

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' là gì. Có phải là viết tắt của tên bảng?
Normandantzig

1
'P' là bí danh cho Người. Nó tuân theo khai báo bảng trong mệnh đề TỪ.
Queue Mann

1
@normandantzig Cả hai đều hợp lệ trong SQL Server trong hầu hết các tình huống.
Bacon Bits
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.