Как преобразовать это вложенное объединение Informix в вложенное объединение TSQL? - PullRequest
1 голос
/ 20 марта 2012

Мне очень трудно с этим преобразованием.Эти вложенные соединения 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 ]

2 голосов
/ 20 марта 2012

Попробуйте это:

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 голос
/ 20 марта 2012

Чьи-то соглашения об именах оставляют желать лучшего. Кроме того, инструкция 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, что может иметь последствия для условий объединения.


Видя комментарий Андрея Гуринова о состоянии tdpur402.t_pono = tdpur402.t_pono, я согласен с ним, что оно странное (я его пропустил, пока не просмотрел его ответ). Значение будет истинным, если tdpur402.t_pono не равно NULL. Я подозреваю опечатку; один из двух '402' должен быть '401', но это не гарантируется.

...