如何将此 Informix 嵌套联接转换为 tsql 嵌套联接?
Posted
技术标签:
【中文标题】如何将此 Informix 嵌套联接转换为 tsql 嵌套联接?【英文标题】:How do I convert this Informix nested join to a tsql nested join? 【发布时间】:2012-04-05 02:57:32 【问题描述】:我很难进行这种转换。那些嵌套的 OUTER 连接对我来说是第一次。
原始 Informix 查询:
from ttdpur401105 tdpur401
, ttdpur400105 tdpur400
-- Problem is here
, outer tarpur002105 arpur002
, outer (ttdpur402105 tdpur402, outer (ttisfc001105 tisfc001 , outer ttcibd001105 tcibd001a ))
, outer ttcibd001105 tcibd001
-- Problem is here
WHERE tdpur401.t_otbp = ' WD005'
and ((tdpur401.t_oltp=1 AND tdpur401.t_qibo <>0) OR(tdpur401.t_oltp=4 AND tdpur401.t_qibo = 0 AND tdpur401.t_qidl<>tdpur401.t_qoor))
and tdpur401.t_fire <> 1
and tdpur401.t_orno = tdpur400.t_orno
and (tdpur400.t_hdst<>25 AND tdpur400.t_hdst<>30 AND tdpur400.t_hdst<>40)
and arpur002.t_orno = tdpur401.t_orno
and arpur002.t_pono = tdpur401.t_pono
and tdpur402.t_orno = tdpur401.t_orno
and tdpur402.t_pono = tdpur402.t_pono
and tisfc001.t_pdno = tdpur402.t_pdno
and tcibd001.t_item = tdpur401.t_item
and tcibd001a.t_item = tisfc001.t_mitm
and (tdpur401.t_orno[1,3]='111' or tdpur401.t_orno[1,4]='1126' )
尝试 T-SQL 查询:
from ttdpur401105 as tdpur401
inner join ttdpur400105 as tdpur400 on tdpur401.t_orno = tdpur400.t_orno
left outer join tarpur002105 as arpur002 on arpur002.t_orno = tdpur401.t_orno and arpur002.t_pono = tdpur401.t_pono
left outer join (ttdpur402105 as tdpur402
left outer join (ttisfc001105 as tisfc001
left outer join ttcibd001105 as tcibd001a on tcibd001a.t_item = tisfc001.t_mitm
and tisfc001.t_pdno = tdpur402.t_pdno) on tdpur402.t_orno = tdpur401.t_orno)
left outer join ttcibd001105 as tcibd001 on tcibd001.t_item = tdpur401.t_item
WHERE tdpur401.t_otbp = ' WD005'
and ((tdpur401.t_oltp=1 AND tdpur401.t_qibo <>0) OR(tdpur401.t_oltp=4 AND tdpur401.t_qibo = 0 AND tdpur401.t_qidl<>tdpur401.t_qoor))
and tdpur401.t_fire <> 1
and (tdpur400.t_hdst<>25 AND tdpur400.t_hdst<>30 AND tdpur400.t_hdst<>40)
and tdpur402.t_pono = tdpur402.t_pono
and substring(tdpur401.t_orno,1,3)='111' or substring(tdpur401.t_orno, 1,4)='1126'
【问题讨论】:
【参考方案1】:试试这个:
from ttdpur401105 as tdpur401
inner join ttdpur400105 as tdpur400 on tdpur401.t_orno = tdpur400.t_orno
left outer join tarpur002105 as arpur002
on arpur002.t_orno = tdpur401.t_orno and arpur002.t_pono = tdpur401.t_pono
left outer join ttdpur402105 as tdpur402
on tdpur402.t_orno = tdpur401.t_orno
left outer join ttisfc001105 as tisfc001
ON tisfc001.t_pdno = tdpur402.t_pdno
left outer join ttcibd001105 as tcibd001a
on tcibd001a.t_item = tisfc001.t_mitm
left outer join ttcibd001105 as tcibd001
on tcibd001.t_item = tdpur401.t_item
WHERE tdpur401.t_otbp = ' WD005'
and ((tdpur401.t_oltp=1 AND tdpur401.t_qibo <>0) OR(tdpur401.t_oltp=4 AND tdpur401.t_qibo = 0 AND tdpur401.t_qidl<>tdpur401.t_qoor))
and tdpur401.t_fire <> 1
and (tdpur400.t_hdst<>25 AND tdpur400.t_hdst<>30 AND tdpur400.t_hdst<>40)
and tdpur402.t_pono = tdpur402.t_pono
and substring(tdpur401.t_orno,1,3)='111' or substring(tdpur401.t_orno, 1,4)='1126'
你还需要检查这一行:
and tdpur402.t_pono = tdpur402.t_pono
我有点困惑。
【讨论】:
这不是我的代码,我还没有听说它为什么存在。但是,是的,它也让我感到困惑。 顺便说一句,您的代码有效。我只需要将 tdpur402.t_pono 线移到连接处。然而,Jonathan Leffler 指出了一些我不知道我必须考虑的事情。如果可以的话,我会为你们俩做绿色检查:( 希望我能在其他地方获得积分。看起来我比乔纳森更需要:)【参考方案2】:某人的命名约定还有很多不足之处。此外,SELECT 语句以 SELECT 开头;看着被斩首的 SQL 感觉很有趣。看来您的总体思路是正确的。
SELECT *
FROM ttdpur401105 AS tdpur401
JOIN ttdpur400105 AS tdpur400 ON tdpur401.t_orno = tdpur400.t_orno
LEFT JOIN tarpur002105 AS arpur002 ON arpur002.t_orno = tdpur401.t_orno
AND arpur002.t_pono = tdpur401.t_pono
LEFT JOIN ttcibd001105 AS tcibd001 ON tcibd001.t_item = tdpur401.t_item
LEFT JOIN (SELECT *
FROM ttdpur402105 AS tdpur402
LEFT JOIN (SELECT *
FROM ttisfc001105 AS tisfc001
LEFT JOIN ttcibd001105 AS tcibd001a
ON tcibd001a.t_item = tisfc001.t_mitm
)
ON tisfc001.t_pdno = tdpur402.t_pdno
)
ON tdpur402.t_orno = tdpur401.t_orno
AND tdpur402.t_pono = tdpur402.t_pono -- ??typo tdpur402.t_pono = tdpur401.t_pono
WHERE tdpur401.t_otbp = ' WD005'
AND ((tdpur401.t_oltp = 1 AND tdpur401.t_qibo <> 0) OR
(tdpur401.t_oltp = 4 AND tdpur401.t_qibo = 0 AND
tdpur401.t_qidl <> tdpur401.t_qoor))
AND tdpur401.t_fire <> 1
AND (tdpur401.t_orno[1,3]='111' OR tdpur401.t_orno[1,4]='1126' )
AND (tdpur400.t_hdst <> 25 AND tdpur400.t_hdst <> 30 AND tdpur400.t_hdst <> 40)
您也许可以在没有那些内部 SELECT 部分的情况下编写它,只需使用更多的 LEFT JOIN 表示法。我认为您需要使用括号来确保正确的解释(或者,至少,我想添加括号来向自己解释解释)。
唯一需要担心的问题是,旧的、非标准的 Informix OUTER 表示法不仅在语法上与新的标准 SQL 表示法不同,而且在某些情况下会产生不同的结果。大多数时候,你会没事的。但是您应该仔细检查翻译后的查询结果,以确保获得您期望的所有数据。总的来说,您可能会发现标准 SQL 产生了您想要的(而旧的表示法可能产生了您实际上并不想要的行)。但是您必须仔细检查。
显然,我没有测试过这段代码。您可能需要使用 AS 子句标记子选择,这可能会对连接条件产生影响。
看到Andrey Gurinov 对tdpur402.t_pono = tdpur402.t_pono
条件的评论,我同意他的看法,这很奇怪(直到扫描他的答案,我才错过了它)。除非tdpur402.t_pono
为NULL,否则它将评估为真。我怀疑是错字;两个“402”之一应该是“401”,但不能保证。
【讨论】:
AS 关键字是必需的,因此使事情复杂化。我已经收到“为‘table_a’指定了多次移动项目列”错误。 这就是我们没有选择列表和表模式的困难;我们不知道您可能需要从哪里拉出什么。您列出了一些列,但可能还有其他列。以上是关于如何将此 Informix 嵌套联接转换为 tsql 嵌套联接?的主要内容,如果未能解决你的问题,请参考以下文章
如何将此嵌套的 JSON 以柱状形式转换为 Pandas 数据框