Cara memilih baris pertama dari gabungan yang mengembalikan baris multple pada kunci utama

15

Ini terkait dengan pertanyaan ini: Bergabung dengan beberapa tabel menghasilkan baris duplikat

Saya memiliki dua tabel yang saya ikuti. Mereka berbagi kunci. Tabel orang memiliki satu nama per kunci utama tetapi tabel email memiliki beberapa email per personId. Saya hanya ingin menampilkan email pertama per orang. Saat ini saya mendapatkan beberapa baris per orang karena mereka memiliki banyak email. Saya menjalankan SQL-Server 2005.

EDIT: Ini adalah T-SQL. Email pertama secara harfiah adalah baris email pertama per orang.

Sunting 2: Email pertama seperti yang saya lihat akan menjadi baris email pertama yang muncul di gabung saat SQL bekerja melalui kueri. Saya tidak masalah email mana yang muncul. Hanya saja tidak lebih dari satu email yang muncul. Saya harap itu membuatnya lebih jelas.

Table1: Person
Table2: Email

Select Person.PersonName, Email.Email
From person 
left join on Person.ID=Email.PersonId;
normandantzig
sumber
3
Apa yang Anda maksud dengan email "pertama"? Kriteria apa yang menentukan "pertama"?
Antrian Mann
1
Apakah Anda mencoba 1 teratas?
Pembalap SQL
3
DBMS mana yang Anda gunakan? Postgres? Peramal?
a_horse_with_no_name
3
The "baris pertama email per orang" tidak benar-benar menceritakan apa-apa. "Pertama" dengan kriteria apa? Tabel SQL tidak memiliki urutan bawaan.
ypercubeᵀᴹ
5
Nah, itu satu kriteria yang valid: "Saya tidak peduli baris mana, hanya satu".
ypercubeᵀᴹ

Jawaban:

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
Sabin Bio
sumber
1
Apa itu 'A'? Apakah ini singkatan dari nama tabel?
normandantzig
2
@normandantzig Itu alias .
Bacon Bits
1
1.) Apakah Anda alias kedua tabel saya menggunakan Dari (Pilih Person.PersonName, Email.Email, ROW_NUMBER () LEBIH DARI (PARTISI DENGAN ORANG.ID ORDER DENGAN Email.Email) SEBAGAI RN Dari orang yang tersisa, bergabunglah dengan Person.ID = Email.PersonId) A Dan 2.) sehingga Anda bisa merujuk kedua kolom menggunakan A sebagai tabel?
normandantzig
4
Apa yang ada di dalam tanda kurung disebut tabel turunan . Ini adalah tabel yang valid, sama seperti tabel dasar tetapi seumur hidup hanya untuk durasi eksekusi query. Itu harus memiliki nama (atau alias) dan @sabin memilih untuk menamainya A. Tabel ini memiliki 3 kolom (PersonName, Email, RN) dan di luar tanda kurung, Anda dapat menggunakan A.Emailseperti yang dapat Anda gunakan tablename.columnnameuntuk setiap tabel lain dalam kode Anda.
ypercubeᵀᴹ
13

Saya akan menggunakan aplikasi luar untuk ini, saya merasa lebih mudah dibaca.

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;
Tuan Magoo
sumber
5

Karena tidak masalah email mana yang muncul. Saya pikir yang berikut ini sangat langsung.

Select Person.PersonName,  MIN(Email.Email)
From person 
left join email 
on Person.ID=Email.PersonId
group by Person.Id, Person.PersonName
JGA
sumber
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
Antrian Mann
sumber
1
Apa itu 'P'. Apakah ini singkatan dari nama tabel?
normandantzig
1
'P' adalah alias untuk Orang. Ini mengikuti deklarasi tabel dalam klausa FROM.
Antrian Mann
1
@normandantzig Keduanya valid dalam SQL Server di sebagian besar situasi.
Bacon Bits