为什么SQL查询在同一个表上以相同的条件连接两次?

时间:2010-03-26 00:59:52

标签: sql-server

我正在研究由其他人开发的SQL Server v8数据库的更改,并且发现了(基于我有限的SQL知识)看起来奇怪且毫无意义的东西。
其中一个视图有一个查询,它在具有相同条件的同一个表上执行两次LEFT OUTER JOIN。这样做有什么理由吗?

查询如下。查看第二行和第三行,它们都加入“SDE_ID”字段上的“te_SDE_Survey”表。另请注意,这些行为表设置了两个不同的别名,并且两个别名都在查询的SELECT部分​​中使用。

SELECT     vs.SLMS_Code, vs.Retail_Date, vs.TagNo, vs.Rego, vs.Model, vs.Company,
           vs.AccountType, viqdp.SDE_ID, bd.Debit_Date, isu.Survey_Date, 
           CASE
             WHEN isu.Q6 IS NOT NULL THEN isu.Q6
             ELSE CASE WHEN returned_surveys.survey_date IS NULL THEN
               CASE WHEN (viqdp.expiryDate < getdate() AND cs.sup1 IS NULL AND cs.sup2 IS NULL
                   AND cs.sup3 IS NULL AND cs.sup5 IS NULL AND cs.sup8 IS NULL AND cs.sup9 IS NULL) THEN 'E'
                 WHEN (viqdp.expiryDate < getdate() AND cs.sup1 = 'F' AND cs.sup2 = 'F' AND cs.sup3 = 'F'
                   AND cs.sup5 = 'F' AND cs.sup8 = 'F' AND cs.sup9 = 'F') THEN 'E'
                 WHEN cs.sup1 = 'T' THEN 'S'
                 WHEN cs.sup2 = 'T' AND (cs.sup8 = 'F' AND cs.sup9 = 'F') THEN 'D'
                 WHEN cs.sup3 = 'T' AND (cs.sup8 = 'F' AND cs.sup9 = 'F') THEN 'D'
                 WHEN cs.sup5 = 'T' AND (cs.sup8 = 'F' AND cs.sup9 = 'F') THEN 'D'
                 WHEN cs.sup8 = 'T' AND (cs.sup2 = 'F' AND cs.sup3 = 'F' AND cs.sup5 = 'F') THEN 'E'
                 WHEN cs.sup9 = 'T' AND (cs.sup2 = 'F' AND cs.sup3 = 'F' AND cs.sup5 = 'F') THEN 'E'
                 WHEN (cs.sup8 = 'T' OR cs.sup9 = 'T') AND (cs.sup2 = 'T' OR cs.sup3 = 'T' OR cs.sup5 = 'T') THEN 'S'
               END
               WHEN (tey.survey_expire_method = 'pre2008') THEN
                 CASE WHEN (datediff(month, viqdp.generate_date, returned_surveys.survey_date) > 1) THEN 'E' END
               WHEN (tey.survey_expire_method = 'expiryDateColumn') THEN
                 CASE WHEN (returned_surveys.survey_date > viqdp.expiryDate) THEN 'E' END
             END
           END AS score_or_exclusion_status,
           CASE WHEN (bd.explanation IS NULL) THEN '' ELSE bd.explanation END AS explanation,
           tey.te_Year
FROM       dbo.te_Vehicle_Sale vs INNER JOIN
           dbo.te_Year tey ON vs.Retail_Date >= tey.Start_Date AND vs.Retail_Date <= tey.End_Date LEFT OUTER JOIN
           dbo.Bad_Data bd ON vs.TagNo = bd.TagNo LEFT OUTER JOIN
           dbo.te_Vehicle_SDESurvey viqdp ON vs.TagNo = viqdp.TagNo LEFT OUTER JOIN
           dbo.te_SDE_Survey isu ON viqdp.SDE_ID = isu.SDE_ID LEFT OUTER JOIN
           dbo.te_SDE_Survey returned_surveys ON viqdp.SDE_ID = returned_surveys.SDE_ID LEFT OUTER JOIN
           dbo.te_SDE_Contact_Suppression cs ON viqdp.SDE_ID = cs.SDE_ID

3 个答案:

答案 0 :(得分:0)

没有理由这样做。这可能是糟糕和懒惰编码实践相结合的结果。

不应将联接放在一行SQL代码的末尾。首选方法:

 SELECT *
 FROM Main_Table
 INNER JOIN Secondary_Table as Sec on Main_Table.ID = Sec.FK

在te_SDE_Survey的一个连接的ON子句中可能存在二次比较,然后程序员发现不再需要它。程序员可能删除了ON子句的第二部分,并没有注意到(急于)由于代码粗糙而已经以相同的方式连接了表

答案 1 :(得分:0)

除了hamlin11的回答之外,可能是为了突出显示中间的巨大wall'o'text与同一个表中的必填字段分开。只是一种突出显示困难文本块的另一种形式。

虽然在连接上很繁琐,但根据所涉及的表的大小,这可能甚至不是一个明显的问题。这种加入会导致探查者感到很悲伤吗?

答案 2 :(得分:0)

可能不正确。也许应该加入一个不同的FK。如果它是正确的,它可能是多余的,但是,它可能是因为最初它连接到该数据的不同表/视图或加入不同的密钥并且为了避免必须更新前缀,这已经完成。

此外,如果这不是一对一的关系,您将得到不同的结果,因为每个LEFT JOIN都会导致结果的倍增。在这种情况下,这很难看出正确,但它确实意味着单连接和双连接版本在面对一对多关系时并不完全相同。

我从未见过SQL Server Management Studio重新格式化我的代码,除非它在视图设计器中。当然,ALTER VIEW / PROCEDURE / FUNCTION保留格式化,因为我一直在INFORMATION_SCHEMA.ROUTINES或syscomments中看到它。

通常,我使用SQL Prompt一致地重新格式化我的代码。