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.