9

我正忙于将使用旧样式语法的查询转换为新的连接语法。我的查询的实质如下:

原始查询

SELECT i.*  
FROM 
  InterestRunDailySum i, 
  InterestRunDetail ird, 
  InterestPayments p
WHERE 
   p.IntrPayCode = 187
   AND i.IntRunCode = p.IntRunCode AND i.ClientCode = p.ClientCode
   AND ird.IntRunCode = p.IntRunCode AND ird.ClientCode = p.ClientCode

新查询

SELECT  i.*
  FROM InterestPayments p
    INNER JOIN InterestRunDailySum i 
      ON (i.IntRunCode = p.IntRunCode AND i.ClientCode = p.ClientCode)
    INNER JOIN InterestRunDetail ird 
      ON (ird.IntRunCode = p.IntRunCode AND ird.IntRunCode = p.IntRunCode)
  WHERE 
    p.IntrPayCode = 187

在此示例中,“原始查询”返回 46 行,其中“新查询”返回超过 800

有人可以向我解释其中的区别吗?我会假设这些查询是相同的。

4

2 回答 2

19

问题在于您加入InterestRunDetail. 你加入了IntRunCode两次。

正确的查询应该是:

SELECT  i.*
  FROM InterestPayments p
    INNER JOIN InterestRunDailySum i 
      ON (i.IntRunCode = p.IntRunCode AND i.ClientCode = p.ClientCode)
    INNER JOIN InterestRunDetail ird 
      ON (ird.IntRunCode = p.IntRunCode AND ird.ClientCode = p.ClientCode)
  WHERE 
    p.IntrPayCode = 187
于 2012-06-22T14:24:00.390 回答
6

“新查询”是与当前用于 JOIN 的 ANSI SQL 标准兼容的查询。

此外,我发现查询 #2 更干净

  • 您几乎被迫考虑并指定两个表之间的连接条件- 您不会意外地在查询中包含笛卡尔积。如果您碰巧列出了 10 个表,但您的WHERE子句中只有 6 个连接条件 - 您将获得比预期更多的数据!

  • 你的WHERE子句没有被连接条件弄得杂乱无章,因此它更干净、不那么凌乱、更容易阅读和理解

  • 您的JOIN类型(是否INNER JOIN, LEFT OUTER JOIN, CROSS JOIN)通常更容易看到 - 因为您将其拼写出来。使用“旧式”语法,这些连接类型之间的差异很难看出,隐藏在您的许多WHERE标准中......

在功能上,两者是相同的——#1 可能迟早会被某些查询引擎弃用。

另请参阅 Aaron Bertrand 的优秀坏习惯踢 - 使用旧式 JOIN 语法博客文章以获取更多信息 - 当你在它的时候 - 阅读所有“踢坏习惯”的帖子 - 所有这些都非常值得!

于 2012-06-22T14:24:35.880 回答