如何从在主键上返回多行的连接中选择第一行

nor*_*zig 15 sql-server-2005 sql-server greatest-n-per-group

这与这个问题有关: Joining multiple tables results in duplicate rows

我有两个要加入的表。他们共用一个钥匙。person 表的每个主键有一个名称,而 email 表的每个 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;
Run Code Online (Sandbox Code Playgroud)

Sab*_*n B 19

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
Run Code Online (Sandbox Code Playgroud)

  • 括号内的内容称为**派生表**。它是一个有效的表,就像基表一样,但它的生命周期仅在查询执行期间。它必须有一个名称(或别名),@sabin 选择将其命名为“A”。该表有 3 列(PersonName、Email、RN),在括号之外,您可以使用“A.Email”,就像您可以对代码中的每个其他表使用“tablename.columnname”一样。 (4认同)
  • @normandantzig 这是一个 [别名](https://technet.microsoft.com/en-us/library/ms187455%28v=sql.105%29.aspx)。 (2认同)

Mis*_*goo 14

我会为此使用外部应用程序,我发现它更具可读性。

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;
Run Code Online (Sandbox Code Playgroud)


小智 5

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
Run Code Online (Sandbox Code Playgroud)


JGA*_*JGA 5

因为显示哪个电子邮件并不重要。我觉得下面一个很直接。

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