我需要将旧的SQL外部联接转换为ANSI。
原因是,我们正在从遗留数据库实例(2000/5?)升级到SQL 2016。
旧版SQL查询: -
选择
- 我要选择的数据 -
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是聚会类型代码,CAT1和CAT2是类别代码。他们只是数据;我抽象了它,因为价值并不重要。
现在,当我尝试用LEFT OUTER JOIN替换* =时,无论是行数还是数据本身,我都会在数据上产生巨大的不匹配。
我正在使用的查询是这样的:
我究竟做错了什么 ?
选择
- 我要选择的数据 -
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(交易对手)表位于* =的左侧。所以这应该转换为所有三个表的LEFT OUTER JOIN。但是,我的解决方案似乎无法正常工作我该如何解决这个问题?我在这做错了什么?
任何帮助将非常感激。提前致谢 :)
编辑
我还有另一个这样的查询:
选择
- 我要选择的数据 -
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表似乎都在同一个表sm上执行LEFT OUTER JOIN。我该如何处理?也许加入同一个表并使用别名sm1和sm2?或者我应该使用sm作为中心表并将连接更改为dvco和d表上的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')
但是,很难知道我是否正确,因为您没有提供样本数据,期望的结果,甚至是完整的查询。
如果你正在进行转换,那么根据我的经验,* =是一个正确的外部连接,而= *就直接转换来说是一个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
感谢您的帮助和对不起的帖子,但我使用SSMS中内置的查询设计器工具快速破解了它。它简单地重构了我的所有查询,并在Join本身上输入了正确的Join,Left或Right,以及Where条件作为AND条件,所以我得到了pre和post的正确数据结果集,有时只是数据排序/订购有点偏。我迷失了截止日期,并且无法提前更新解决方案。再次感谢您的帮助。希望这也有助于其他人!
如果Join条件相同且过滤器也是如此,因为数据是100%匹配,为什么排序/排序有点偏离仍然有点不确定。
要使查询设计器工作,只需选择旧版SQL,然后按Ctrl + Shift + Q或转到主菜单工具栏=>查询=>编辑器中的设计查询打开查询设计器。
而已。这会将您的遗留代码重构为新的ANSI标准。您将获得转换后的查询以及可以复制和测试的新联接。我有100%的时间工作,除了在某些情况下排序不匹配,您可以通过在前后添加一个简单的order by子句来检查以比较数据。
作为参考,我用这篇文章交叉检查: