如何将此 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 嵌套联接?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jq 将此嵌套对象转换为扁平对象?

如何将此嵌套的 JSON 以柱状形式转换为 Pandas 数据框

我如何将此查询编写为联接而不是相关查询?

Informix 多连接

如何在javascript中将嵌套对象转换为对象数组? [关闭]

如何将嵌套的 np.array 转换为 pandas 数据框单列