在 SQL Server 中水平连接两个以上的表

use*_*060 4 sql t-sql outer-join sql-server-2008

以下是架构

+---------+---------+
| Employee Table    |
+---------+---------+
| EmpId   | Name    | 
+---------+---------+
| 1       | John    |
| 2       | Lisa    |
| 3       | Mike    |
|         |         |
+---------+---------+

+---------+-----------------+
| Family   Table            |
+---------+-----------------+
| EmpId   | Relationship    | 
+---------+-----------------+
| 1       | Father          |
| 1       | Mother          |
| 1       | Wife            |
| 2       | Husband         |
| 2       | Child           |
+---------+-----------------+

+---------+---------+
| Loan  Table       |
+---------+--------+
| LoanId  | EmpId  | 
+---------+--------+
| L1      | 1      |
| L2      | 1      |
| L3      | 2      |
| L4      | 2      |
| L5      | 3      |
+---------+--------+
Run Code Online (Sandbox Code Playgroud)
  • 员工表和家庭表是一对多的关系
  • Employee Table 和 Loan Table 有很多关系

我试过 Joins 但它给出了多余的行。

现在所需的输出将是

+---------+---------+--------------+---------+
| EmpId   | Name    | RelationShip | Loan    | 
+---------+---------+--------------+---------+
| 1       | John    | Father       | L1      |
| -       | -       | Mother       | L2      |
| -       | -       | Wife         | -       |
| 2       | Lisa    | Husband      | L3      |
| -       | -       | Child        | L4      |
| 3       | Mike    | -            | L5      |
|         |         |              |         |
+---------+---------+--------------+---------+    
Run Code Online (Sandbox Code Playgroud)

Gor*_*off 5

看起来您正在尝试将贷款“按顺序”分配给家庭表中的行。解决这个问题的方法是首先获取正确的行,然后获取分配给行的贷款。

正确的行(和前三列)是:

select f.EmpId, e.Name, f.Relationship
from family f join
     Employee e
     on f.empid = e.empid;
Run Code Online (Sandbox Code Playgroud)

请注意,这不会将连字符放入重复值的列中,而是放入实际值。尽管您可以在 SQL 中安排连字符,但这是一个坏主意。SQL 结果以表格的形式存在,表格是无序集合,每列和每行都有值。当您开始输入连字符时,您取决于顺序。

现在的问题是加入贷款。这实际上很容易,通过使用row_number()添加一个join键:

select f.EmpId, e.Name, f.Relationship, l.LoanId
from Employee e left join
     (select f.*, row_number() over (partition by f.EmpId order by (select NULL)) as seqnum
      from family f
     ) f 
     on f.empid = e.empid left join
     (select l.*, row_number() over (partition by l.EmpId order by (select NULL)) as seqnum
      from Loan l
     ) l
     on f.EmpId = l.EmpId and f.seqnum = l.seqnum;
Run Code Online (Sandbox Code Playgroud)

请注意,这并不能保证给定员工的贷款分配顺序。您的数据似乎没有足够的信息来处理更一致的分配。