SQL Server WHERE用于多个表

时间:2015-01-21 15:14:45

标签: sql sql-server

在连接3个或更多表时(所有内部连接都有)指定每个匹配的要求是否有任何优缺点?

练习1:

SELECT 
    tb1.InvoiceNum, tb2.Name, tb1.DueDate, tb3.TranDate
FROM 
    MFGSYS.PUB.CashDtl tb3, MFGSYS.PUB.Customer tb2, MFGSYS.PUB.InvcHead tb1
WHERE 
    tb2.Company = tb1.Company 
    AND tb2.CustNum = tb1.CustNum 
    AND tb3.Company = tb2.Company 
    AND tb3.Company = tb1.Company 
    AND tb3.InvoiceNum = tb1.InvoiceNum ((tb1.Company='MC') 
    AND (tb1.Posted=1))
ORDER BY 
    tb1.InvoiceNum

我离开tb3.Company = tb1.Company是否重要,因为只选择了来自tb3' where 'tb3.Company = tb2.Company的记录,而且只有tb2中选择了tb2.Company = tb1.Company的记录?

通过删除多余的连接是否有获得(或丢失)的效率?

编辑:这实际上是由ODBC连接的MSQuery生成的SQL命令(Progress OpenEdge 10.1B)。但我可以添加或删除'加入'

3 个答案:

答案 0 :(得分:4)

编写此查询的正确方法是使用显式join语法:

SELECT tb1.InvoiceNum, tb2.Name, tb1.DueDate, tb3.TranDate
FROM MFGSYS.PUB.InvcHead tb1 JOIN
     MFGSYS.PUB.Customer tb2
     ON tb2.Company = tb1.Company AND
        tb2.CustNum = tb1.CustNum JOIN
     MFGSYS.PUB.CashDtl tb3
     ON tb3.Company = tb1.Company AND
        tb3.InvoiceNum = tb1.InvoiceNum
WHERE tb1.Company = 'MC' AND tb1.Posted = 1
ORDER BY tb1.InvoiceNum;

如果可能,您应该只在on条件下坚持使用两个表格。当然不可能时,使用多个表格。冗余条件是不必要的(根据定义)并使查询更难理解。

答案 1 :(得分:0)

说到sql-server,我发现在很多情况下嵌套选择比连接更快(特别是如果你有大量的连接。)当你从每个连接中获取单个列值时,最好使用嵌套选择。连接表。

在您的查询中,大多数工作是针对tb1完成的,您只需从其他表中获取一些数据进行演示,因此您可以尝试这样做:

SELECT tb1.InvoiceNum,
       (SELECT tb2.Name FROM MFGSYS.PUB.Customer tb2 WHERE tb2.company = tb1.company AND tb2.CustNum = tb1.CustNum) AS Name,
       tb1.DueDate,
       (SELECT tb3.TranDate FROM MFGSYS.PUB.CashDtl tb3 WHERE tb3.Company = tb1.Company AND tb3.InvoiceNum = tb1.InvoiceNum) AS TranDate
FROM MFGSYS.PUB.InvcHead tb1
WHERE tb1.Company = 'MC' AND tb1.Posted = 1
ORDER BY tb1.InvoiceNum

可能比加入更快,可能不会,你必须尝试。

答案 2 :(得分:-4)

首先,你所拥有的不是一个明确的联接。它是交叉连接的粗略版本,不需要每个表之间的链接。其次,删除多余的WHERE子句将会改进代码并提高性能。但正如Gordon Linoff建议的那样,尝试使用明确的JOIN语法,因为它们简洁且通常更快。