将 Legacy SQL Outer JOIN *=, =* 转换为 ANSI

Convert Legacy SQL Outer JOIN *=, =* to ANSI

我需要将遗留 SQL 外连接转换为 ANSI。

原因是,我们正在从旧版数据库实例 (2000/5 ?) 升级到 SQL 2016。

旧版 SQL 查询 :-

SELECT

--My Data to Select--

 FROM counterparty_alias ca1,  
  counterparty_alias ca2,  
  counterparty cp,  
  party p  
 WHERE cp.code *= ca1.counterparty_code AND
  ca1.alias = 'Party1' AND  
  cp.code *= ca2.counterparty_code AND  
  ca2.alias = 'Party2' AND
  cp.code *= p.child_code AND  
  cp.category in ('CAT1','CAT2')

这里Party1和Party2是party type codes,CAT1和CAT2是category codes。它们只是数据;我已经抽象了它,因为值并不重要。

现在,当我尝试用 LEFT OUTER JOIN 替换 *= 时,我发现数据存在巨大的不匹配,无论是行数还是数据本身。

我正在使用的查询是这样的:

我做错了什么?

SELECT

--My Data to Select--

 FROM 
  counterparty cp  
  LEFT OUTER JOIN counterparty_alias ca1 ON cp.code = ca1.counterparty_code  
  LEFT OUTER JOIN counterparty_alias ca2 ON cp.code = ca2.counterparty_code      
  LEFT OUTER JOIN party p  ON  cp.code = p.child_code
 WHERE  
  ca1.alias = 'Party1' AND  
  ca2.alias = 'Party2' AND
  cp.category in ('CAT1','CAT2')

显然,在所有三个遗留连接中,cp(交易对手)table 位于 *= 的左侧。所以这应该转化为 LEFT OUTER JOIN WITH 所有三个 tables。但是,我的解决方案似乎不起作用 我怎样才能解决这个问题 ?我在这里做错了什么?

如有任何帮助,我们将不胜感激。提前致谢:)

编辑

我还有一个这样的查询:

SELECT

--My Data to Select--

FROM dbo.deal d,  
 dbo.deal_ccy_option dvco,  
 dbo.deal_valuation dv,  
 dbo.strike_modifier sm  
WHERE d.deal_id = dvco.deal_id  
AND d.deal_id = dv.deal_id      
AND dvco.base + dvco.quoted *= sm.ccy_pair  
AND d.maturity_date *= sm.expiry_date  

在这种情况下,dvco 和 d tables 似乎都在同一个 table sm 上进行 LEFT OUTER JOIN。我该如何处理? 也许加入同一个 table 并使用别名 sm1 和 sm2 ? 或者我应该使用 sm 作为中央 table 并将连接更改为 dvco 和 d tables 上的 RIGHT OUTER JOIN ?

我认为您的翻译存在问题,您在 where 子句而不是 on 子句中的正确表格中使用了条件。
当我尝试翻译它时,这是我得到的翻译:

FROM counterparty cp
LEFT JOIN counterparty_alias ca1 ON cp.code = ca1.counterparty_code 
                                AND ca1.alias = 'Party1'
LEFT JOIN counterparty_alias ca2 ON cp.code *= ca2.counterparty_code 
                                AND ca2.alias = 'Party2'
LEFT JOIN party p ON cp.code = p.child_code
WHERE cp.category in ('CAT1','CAT2')

但是,很难知道我是否正确,因为您没有提供样本数据、所需结果,甚至没有提供完整的查询。

如果您正在进行转换,根据我的经验,就直接转换而言,*= 是 RIGHT OUTER JOIN,而 =* 是 LEFT OUTER JOIN。

我现在正在转换数百个存储过程和视图,并且通过测试这是匹配的。我首先 运行 将查询作为原始查询,然后进行更改并使用符合 ANSI 的代码重新 运行 它。

为了在我们的应用程序中保持一致,返回的数据需要相同。

所以对于你的第二个查询,我认为它看起来像这样:

 FROM dbo.deal d  
  INNER JOIN dbo.deal_ccy_option dvco ON d.deal_id = dvco.deal_id
  INNER JOIN  dbo.deal_valuation dv ON d.deal_id = dv.deal_id 
  RIGHT OUTER JOIN  dbo.strike_modifier sm ON d.maturity_date = sm.expiry_date
  AND (dvco.base + dvco.quoted) = sm.ccy_pair 

感谢您的帮助,对迟到的 post 深表歉意,但我使用 SSMS 中内置的查询设计器工具快速破解了它。它只是重构了我所有的查询,并输入了正确的 Join,Left 或 Right,以及 Where 条件作为 Join 本身的 AND 条件,所以我得到了 pre 和 post 的正确数据结果集,只是有时数据 sorting/ordering 有点偏差。 我迷失了最后期限,无法更早地更新解决方案。再次感谢您的帮助。希望这对其他人也有帮助!!

仍然有点不确定为什么 ordering/sorting 在连接条件相同且过滤器相同的情况下有点偏离,因为数据是 100% 匹配。

To get the query Designer to Work , just select your legacy SQL, and open the Query Designer by pressing Ctrl + Shift + Q or Goto Main Menu ToolBar => Query => Design Query in Editor.

就是这样。这会将您的遗留代码重构为新的 ANSI 标准。您将使用可以复制和测试的新联接获得转换后的查询。我 100% 的时间都在工作,除了在某些排序不匹配的情况下,您可以通过向 pre 和 post 添加一个简单的 order by 子句来比较数据来检查。

作为参考,我用这个 post 进行了交叉检查:

http://sqlblog.com/blogs/john_paul_cook/archive/2013/03/02/using-the-query-designer-to-convert-non-ansi-joins-to-ansi.aspx