SQL Server-内部和外部连接在一起

SQL Server-内部和外部连接在一起,sql,sql-server,inner-join,outer-join,Sql,Sql Server,Inner Join,Outer Join,在编写SQL Server的SQL查询时需要一些帮助。我有以下三个表的数据模型 表1 Seq ID Name 1 1234 Abc 2 4567 Pqr 3 7890 Xyz 表2 Seq Table1Id Table3Seq 1 1234 1 2 1234 2 3 7890 3 表3 Seq Status 1 Rejected 2 Accepted 3 Pending 我的要求

在编写SQL Server的SQL查询时需要一些帮助。我有以下三个表的数据模型

表1

Seq   ID   Name
1    1234   Abc
2    4567   Pqr
3    7890   Xyz
表2

Seq Table1Id Table3Seq
1    1234       1
2    1234       2
3    7890       3
表3

Seq  Status
1    Rejected
2    Accepted
3    Pending
我的要求如下。我希望表1中的所有记录都具有表3中的最新状态(如果存在)。因此,正如我们可以看到的,对于Id
1234
,表3中有两条记录匹配(通过表2),但是我想要接受的最新记录。但是在表1
4567
中有一条记录,在表2中没有任何记录,因此我可以根据状态显示为空

Number    Name     Status
1234      Abc      Accepted
4567      Pqr      
7890      Xyz      Pending 
我想,我们可能需要同时使用外部联接和内部联接,但是到目前为止,我无法找到正确的查询。当我尝试使用
MAX
仅使用外部联接时,它仍然会针对
1234
提供两条记录,而当我使用内部联接时,则在输出中不会获得记录
4567

select a.ID, a.Name, c.Status
from table1 a
left outer join (select max(b.seq) AS SEQ, b.table1id from table2 b group by b.table1id) t2 on a.id = t2.table1id
left outer join table2 t2b on t2.seq = t2b.seq and t2.table1id = t2b.table1id
left outer join table3 c on t2b.table3seq = c.seq
也许有更有效的方法,但这会给你你想要的结果。基本上,将表1连接到表2的一个子集,获取每个记录的最大序列,然后再次连接到表2以获取到表3的链接,然后连接到表3以获取状态

所有连接都保留在外部,因此您将以空状态返回pqr结果

也许有更有效的方法,但这会给你你想要的结果。基本上,将表1连接到表2的一个子集,获取每个记录的最大序列,然后再次连接到表2以获取到表3的链接,然后连接到表3以获取状态

所有联接都保留在外部,因此您将以空状态返回pqr结果。

使用两个联接:

SELECT Number, Name, Status FROM
        (SELECT Table1.ID AS Number, Table1.Name, Table3.Status, 
        ROW_NUMBER() OVER (PARTITION BY Table1.Number ORDER BY table3.Seq DESC) AS RN
        FROM Table1
        LEFT OUTER JOIN Table2 ON Table1.ID=Table2.Table1ID
        LEFT OUTER JOIN Table3 ON Table3.seq=table2.Table3Seq)MyTable
        WHERE MyTable.RN=1
使用两个联接:

SELECT Number, Name, Status FROM
        (SELECT Table1.ID AS Number, Table1.Name, Table3.Status, 
        ROW_NUMBER() OVER (PARTITION BY Table1.Number ORDER BY table3.Seq DESC) AS RN
        FROM Table1
        LEFT OUTER JOIN Table2 ON Table1.ID=Table2.Table1ID
        LEFT OUTER JOIN Table3 ON Table3.seq=table2.Table3Seq)MyTable
        WHERE MyTable.RN=1

在SQL Server中执行此操作的一种方法是使用
outerapply
。此方法通常具有最佳性能:

select t1.*, t3.status
from table1 t1 outer apply
     (select top 1 t3.*
      from table2 t2 join
           table3 t3
           on t2.table3seq = t3.seq
      where t1.id = t2.table1id
      order by t2.id desc
     ) t3;

适当的索引是
table2(table1id,table3seq,id)
table3(seq,status)

在SQL Server中执行此操作的一种方法是使用
outer apply
。此方法通常具有最佳性能:

select t1.*, t3.status
from table1 t1 outer apply
     (select top 1 t3.*
      from table2 t2 join
           table3 t3
           on t2.table3seq = t3.seq
      where t1.id = t2.table1id
      order by t2.id desc
     ) t3;

适当的索引是
table2(table1id,table3seq,id)
table3(seq,status)

您尝试了哪些查询?您现在怎么看1234的第二条记录是最新的?是否有datetime字段或其他内容?Hi@haytem,表3中较高序列号对应的值被假定为最新的。您尝试过哪些查询?您现在如何确定1234的第二条记录是最新的?是否有datetime字段或其他内容?Hi@haytem,表3中较高序列号对应的值被认为是最新的。感谢mate的快速帮助。我的问题解决了。实际上,我也尝试过使用MAX(),但不幸的是,我错过了GROUPBY子句:)谢谢你的快速帮助。我的问题解决了。实际上,我也尝试过使用MAX(),但不幸的是,我错过了GROUPBY子句:)谢谢@Gordon。。我也会尝试一下,看看是否能以更好的性能为我提供所需的输出。谢谢@Gordon。。我也会尝试一下,看看是否能以更好的性能提供我想要的输出。