Birincil anahtarda çok satır içeren bir birleşimden ilk satırı seçme


15

Bu şu soru ile ilgilidir: Birden çok tabloya katılmak yinelenen satırlarla sonuçlanır

Katıldığım iki tablo var. Bir anahtarı paylaşıyorlar. Kişi tablosunun birincil anahtar başına bir adı vardır, ancak e-posta tablosunda kişi kimliği başına birden çok e-posta bulunur. Kişi başına yalnızca ilk e-postayı göstermek istiyorum. Şu anda birden fazla e-postaları olduğu için kişi başına birden fazla satır alıyorum. SQL-Server 2005 çalıştırıyorum.

EDIT: Bu T-SQL. İlk e-posta, kelimenin tam anlamıyla kişi başına ilk e-posta satırıdır.

Edit 2: Gördüğüm gibi ilk e-posta SQL sorgu aracılığıyla çalışır gibi birleştirme gösterir ilk e-posta satırı olurdu. Hangi e-postanın göründüğü önemli değil. Yalnızca birden fazla e-posta görünmüyor. Umarım bu daha net olur.

Table1: Person
Table2: Email

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

3
"İlk" e-posta ile ne demek istiyorsun? Ne tür kriterler "ilk" i belirler?
Sıra Mann

1
ilk 1'i denedin mi
Racer SQL

3
Hangi DBMS'yi kullanıyorsunuz? Postgres? Oracle?
a_horse_with_no_name

3
"Kişi başı ilk e-posta satır" gerçekten bize bir şey söylemez. Hangi kriterlere göre "İlk"? SQL tablolarının doğal bir sırası yoktur.
ypercubeᵀᴹ

5
Bu geçerli bir kriter: "Hangi sırayı umursamıyorum, sadece bir tane".
ypercubeᵀᴹ

Yanıtlar:


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' nedir? Tablo adının bir kısaltması mı?
normandantzig

2
@normandantzig Bu bir takma ad .
Bacon Bits

1
1.) Kimden (Person.PersonName, Email.Email, ROW_NUMBER () OVER (Person.ID SİPARİŞ TARAFINDAN BÖLÜME Email.Email) AS RN kullanarak Person.ID = Email.PersonId) A Ve 2.) böylece tabloyu A kullanarak her iki sütuna da başvurabilirsiniz?
normandantzig

4
Parantezin içindekilere türetilmiş tablo denir . Bu, temel tablolar gibi geçerli bir tablodur ancak ömrü yalnızca sorgu yürütme süresi içindir. Bir adı (veya takma adı) olmalı ve @sabin adı seçti A. Bu tablonun 3 sütunu vardır (PersonName, Email, RN) ve parantezlerin dışında, kodunuzdaki diğer tüm tablolarda A.Emailkullanabileceğiniz gibi kullanabilirsiniz tablename.columnname.
ypercubeᵀᴹ

13

Bunun için bir dış uygulama kullanırdım, daha okunabilir buluyorum.

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

Hangi e-postanın göründüğü önemli değil. Aşağıdakilerin çok doğrudan olduğunu düşünüyorum.

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' nedir. Tablo adının bir kısaltması mı?
normandantzig

1
'P' Kişi için bir takma addır. FROM yan tümcesindeki tablo bildirimini izler.
Sıra Mann

1
@normandantzig Her ikisi de çoğu durumda SQL Server'da geçerlidir.
Bacon Bits
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.