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

Posted

技术标签:

【中文标题】如何从返回主键多行的连接中选择第一行【英文标题】:How to select first row from a join that returns multiple rows on the primary key 【发布时间】:2021-04-02 06:37:33 【问题描述】:

我有两个要加入的表。他们共享一把钥匙。 employee 表的每个主键有一个名称,但email 表的每个 employeeId 有多个电子邮件。

我只想显示每位员工的第一封电子邮件。目前我每个员工都有多行,因为他们有多封电子邮件。我正在运行 SQL Server 2019。

编辑:我看到的第一封电子邮件将是连接中显示的第一封电子邮件行,因为 SQL 通过查询工作。我不关心出现哪个电子邮件。只有不超过一封电子邮件出现。我希望这能让它更清楚。

我当前的查询:

Select Employee.PersonName, Email.Email
From Employee
left join on Employee.ID = Email.employeeId;

【问题讨论】:

【参考方案1】:

假设您有以下表格:

    员工(Id、PersonName) 电子邮件(Id、EmployeeId*、电子邮件)

你可以做的是使用ROW_NUMBER EmployeeId 分区和Email Id 排序:

   SELECT Employee.PersonName, Email.Email
     FROM Employee
LEFT JOIN (SELECT EmployeeId, Email, ROW_NUMBER(PARTITION BY EmployeeId ORDER BY Id FROM Email) RN) Email
          ON (Employee.Id = Email.EmployeeId)
    WHERE Email.RN = 1

【讨论】:

【参考方案2】:

一种方法使用子查询:

select ep.personname, em.*
from employee ep
cross apply (
    select top (1) em.email 
    from email em   
    where em.employeeid = ep.id 
    order by em.email
) em

如果你只想要电子邮件而不需要其他任何东西,聚合也可以:

select ep.personname, 
    (select min(em.email) from email em where em.employeeid = ep.id) as email
from employee ep

或者:

select ep.personname, min(em.email) as email
from employee ep
left join email em on em.employeeid = ep.id
group by ep.id, ep.personname

【讨论】:

以上是关于如何从返回主键多行的连接中选择第一行的主要内容,如果未能解决你的问题,请参考以下文章

如何使用子查询的多行返回值插入表中?

Oracle 从主键列中选择返回空值?

SQL 从两个表中选择数据(一行 -> 多行)

在一行上返回函数中的多个主键列。 PLSQL、SQL ORACLE 开发

PL/SQL - 如何从连接表中返回单行

四.Oracle聚合函数和内外全连接