【问题标题】:How do I convert this Informix nested join to a tsql nested join?如何将此 Informix 嵌套联接转换为 tsql 嵌套联接?
【发布时间】: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'

【问题讨论】:

    标签: sql-server tsql join informix outer-join


    【解决方案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 Gurinovtdpur402.t_pono = tdpur402.t_pono 条件的评论,我同意他的看法,这很奇怪(直到扫描他的答案,我才错过了它)。除非tdpur402.t_pono 为NULL,否则它将评估为真。我怀疑是错字;两个“402”之一应该是“401”,但不能保证。

    【讨论】:

    • AS 关键字是必需的,因此使事情复杂化。我已经收到“为‘table_a’指定了多次移动项目列”错误。
    • 这就是我们没有选择列表和表模式的困难;我们不知道您可能需要从哪里拉出什么。您列出了一些列,但可能还有其他列。
    猜你喜欢
    • 2015-06-16
    • 2020-12-01
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 2010-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多