这个SQL语法如何工作?

时间:2013-04-05 21:21:59

标签: sql sql-server

我今天遇到了另一个使用SQL Server查询设计器工具生成的开发人员。 我讨厌查询设计器,但我一直在努力弄清楚它做了什么。我以前从未见过像这样的语法,也不理解它。它是如何工作的?

特别是将多个ON子句连接在一起,与JOIN子句分开,这些子句会让我失望。

SELECT *
FROM  dbo.tblDealStatus
    RIGHT OUTER JOIN dbo.tblUser
            RIGHT OUTER JOIN dbo.tblOwnerLocation
                     INNER JOIN dbo.tblOwner
                          INNER JOIN dbo.tblDeal
                           ON dbo.tblOwner.OwnerID = dbo.tblDeal.OwnerID
                      ON dbo.tblOwnerLocation.DealID = dbo.tblDeal.DealID
             ON dbo.tblUser.UserID = dbo.tblDeal.CHK_Contact
            LEFT OUTER JOIN dbo.tblCompany AS tblCompany_1
                    INNER JOIN dbo.tblParticipation
                     ON tblCompany_1.CompanyID = dbo.tblParticipation.CompanyID
             ON dbo.tblDeal.ParticipationID = dbo.tblParticipation.ParticipationID
     ON /*...
      ....so on and so forth...*/

1 个答案:

答案 0 :(得分:3)

首先,我明确规定,不要在同一个查询中混合左右连接。可以将所有连接切换到左连接,仅此一项就可以更容易地找出正在发生的事情。

接下来放弃选择*。在具有连接的查询中,它永远不会适用,因为您在两个或多个字段(连接字段)中返回相同的数据,这会浪费宝贵的网络和数据库处理时间。

我认为奇怪的ON正在强迫查询按特定顺序进行。它们很糟糕,不应该在我看来使用,因为它们难以维护并且难以让开发人员理解,因为它们不常见且完全不需要。只需反转右连接并按需要加入它们的顺序放置表可能会解决这个问题。如果不是,您可能需要一些派生表来获取正确的数据。请注意,在反转它时,您可能需要将这些内部联接更改为其他内容。现在它是如此混乱,很可能它不会返回正确的结果。因此,在重写时,您可能希望查看更改是否会更改结果,同时您还需要使用判断来确定更改是否是针对错误查询的修复,或者是否将不正确的更改转换为可维护的内容。

如果写这个烂摊子的开发人员还在那里,我会强迫他用更标准的SQL重写,并告诉他禁止他再次使用查询设计器。就我而言,这无法进行代码审查。

如果我重写这个,我会寻找应该在查询中的第一个表并从那里开始工作。我个人现在的猜测是,它将是tblDeal表,但我不知道你的数据模型,所以我可能是错的。