将 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 进行了交叉检查:
我需要将遗留 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 进行了交叉检查: