INNER JOIN vs CROSS JOIN vs CROSS APPLY

时间:2017-03-03 19:37:36

标签: sql sql-server join

SQL的一个乐趣是,通常有多种方法可以做同样的事情,所以最好的"?

在这种情况下,我正在插入来自“导入”的记录。表并为他们提供默认的安全级别' Viewer' (可以在不同的数据库中具有不同的密钥ID)。我可以通过至少三种不同的方式(甚至可能更多)来做到这一点:CROSS JOIN,CROSS APPLY和INNER JOIN。有关哪种性能或设计目的最佳的建议?我倾向于十字架申请。

这个问题可能已经得到解答,但我找不到,最近我在开发过程中不断遇到这种需求,所以我不妨学习最好的方法。

以下是3个示例语句。哪个是加入SecRole表的最佳方式?

INSERT INTO LocStaff (LocationID, StaffID, SecRoleID)
    SELECT i.LocationID, s.StaffID, sr.SecRoleID
    FROM IntStaff i
        JOIN Staff s ON i.EmployeeID = s.StaffNumber
        CROSS JOIN SecRole sr
    WHERE sr.Name = 'Viewer' 

INSERT INTO LocStaff (LocationID, StaffID, SecRoleID)
    SELECT i.LocationID, s.StaffID, sr.SecRoleID
    FROM IntStaff i
        JOIN Staff s ON i.EmployeeID = s.StaffNumber
        JOIN SecRole sr ON sr.Name = 'Viewer'

INSERT INTO LocStaff (LocationID, StaffID, SecRoleID)
    SELECT i.LocationID, s.StaffID, sr.SecRoleID
    FROM IntStaff i
        JOIN Staff s ON i.EmployeeID = s.StaffNumber
        CROSS APPLY (SELECT TOP 1 SecRoleID FROM SecRole WHERE Name = 'Viewer') sr

2 个答案:

答案 0 :(得分:1)

前两个是等价的。在这种情况下,无论是使用内连接还是交叉连接,都是首选。我想我通常会使用cross join,因为表之间没有真正的连接条件

注意:当意图是表格之间具有匹配条件的“真实”cross join时,永远不会使用inner join

cross apply没有做同样的事情。它只选择一行。如果您打算获得最多一个匹配的行,请使用cross apply。如果打算获得一个匹配的行,则使用outer apply

答案 1 :(得分:0)

我们只在表中没有任何共同列(不是最佳结构设计!)或我们需要所有可能的情况时才使用交叉连接(或仅关键字Join)。我不知道你的表结构,但我假设表SecRole没有Staff和InsStaff的外键或公共键。在这种情况下,我将使用右连接(外连接)来获取Staff和InsStaff之间的第一个内连接的所有结果,然后将它们放在SecRole所需记录旁边。

这是右连接的概念 http://www.dofactory.com/sql/right-outer-join