如何将此Informix嵌套连接转换为tsql嵌套连接?

时间:2012-03-20 15:53:44

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

我在这次转换中遇到了很多困难。那些嵌套的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'

2 个答案:

答案 0 :(得分:2)

试试这个:

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 

我对此感到有点困惑。

答案 1 :(得分:1)

某些人的命名惯例还有很多不足之处。另外,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,否则它将评估为true。我怀疑是一个错字;其中一个&#403; 402&#39;应该是&#39; 401&#39;,但这并不能保证。