Oracle-转换 SQL 到 ANSI SQL

Oracle-Conveting SQL to ANSI SQL

这是关于将查询转换为 ANSI SQL。我尝试使用 Oracle 旧语法编写此查询,但它引发了以下错误,因此我最终将其更改为如下所示。经过研究,我发现ANSI SQL支持这样的要求。

错误:一个 table 最多可以与其他 table 个提示

这是我编写的有效查询,但很高兴知道是否有方法可以用 ANSI-SQL 或使用旧的外部连接语法重写。我正在寻找要重写的联合查询,因为 with 子句中的其他查询工作正常。

    WITH BOM_PARENT AS (
    SELECT MX.SAP_MATNR MATNR
         , TRIM(I.IPRODUCTION) IPRODUCTION
         , TRIM(I.IDRAWING) IDRAWING
         , TRIM(M.BCHLD) BCHLD
         , M.BSEQ BSEQ
         , PX.WERKS WERKS
         , M.BPSCP MENGE
         , UX.SAP_UOM MEINS
         , I.IUMS
     FROM XX_MAIN.XX_BPCS_IIM I
        , XX_MAIN.XX_BPCS_MPB M
        , XX_MAIN.XX_MATER_XREF MX
        , XX_MAIN.XX_TRUNK_XREF PX
        , XX_MAIN.XX_MP_UNIT_XREF UX
    WHERE TRIM(I.IPRODUCTION) = TRIM(M.BPROD) 
      AND TRIM(MX.PROD_MATNR) = TRIM(I.IPRODUCTION)
      AND MX.CONV_FACTOR = TO_CHAR(I.IUMCN) 
      AND I.IUMS  = UX.LEGACY_UOM
      AND UX.SOURCE = 'AP'
      AND I.SOURCE = PX.SOURCE
      AND I.ENTITY = PX.LEGACY_PLANT
      AND I.ENTITY = 'SG' 
      AND I.IITYP = '4'
      --AND PX.WERKS IN ('1379')
      AND MX.SAP_MTART <> 'ZPRD'
    )
    , BOM_CHILDS AS
    (
     SELECT  B.*,
             X.SAP_MATNR IDNRK
           , ROW_NUMBER () OVER ( PARTITION BY B.MATNR,B.WERKS ORDER BY B.MATNR,B.WERKS) ID_ITEM_NO  
           , X.PROD_MATNR IDNRK_IPRODUCTION
           , X.DRAWING_MATNR IDNRK_IDRAWING     
      FROM  BOM_PARENT B
          , XX_MAIN.XX_MATER_XREF X
    WHERE  B.BCHLD = TRIM(X.PROD_MATNR )
      AND X.SAP_MTART <> 'ZPRD'
      AND X.SOURCE = 'AP'
    )
    SELECT DISTINCT C.MATNR
         , C.IPRODUCTION
         , C.IDRAWING
         , C.WERKS
         , (C.ID_ITEM_NO*10) ID_ITEM_NO
         , C.BSEQ
         , C.IDNRK
         , C.IDNRK_IPRODUCTION
         , C.IDNRK_IDRAWING
         , C.MENGE BPSCP
         , STPO.MENGE  STPO_MENGE
         , C.MEINS MEINS
         , C.IUMS IUMS
         , STPO.MEINS STPO_MEINS
      FROM BOM_CHILDS C
         , XX_MAIN.XX_MAST MAST
         , XX_MAIN.XX_STPO STPO
      WHERE C.MATNR = MAST.MATNR
       AND MAST.STLNR = STPO.STLNR
       AND MAST.STLAN = '1'
       AND MAST.WERKS = C.WERKS
       AND STPO.IDNRK = C.IDNRK
    UNION
    SELECT DISTINCT C.MATNR
         , C.IPRODUCTION
         , C.IDRAWING
         , C.WERKS
         , (C.ID_ITEM_NO*10) ID_ITEM_NO
         , C.BSEQ
         , C.IDNRK
         , C.IDNRK_IPRODUCTION
         , C.IDNRK_IDRAWING
         , C.MENGE BPSCP
         , STPO.MENGE  STPO_MENGE
         , C.MEINS MEINS
         , C.IUMS IUMS
         , STPO.MEINS STPO_MEINS
      FROM BOM_CHILDS C
         , XX_MAIN.XX_MAST MAST
         , XX_MAIN.XX_STPO STPO
      WHERE C.MATNR = MAST.MATNR(+)
       AND MAST.STLNR = STPO.STLNR(+)
       AND MAST.STLAN(+) = '1'
       AND MAST.WERKS(+) = C.WERKS
       AND STPO.IDNRK IS NULL
    ORDER BY MATNR,WERKS,ID_ITEM_NO,BSEQ;

此部分可能导致问题:

  FROM BOM_CHILDS C
     , XX_MAIN.XX_MAST MAST
     , XX_MAIN.XX_STPO STPO
  WHERE C.MATNR = MAST.MATNR(+)
   AND MAST.STLNR = STPO.STLNR(+)
   AND MAST.STLAN(+) = '1'
   AND MAST.WERKS(+) = C.WERKS
   AND STPO.IDNRK IS NULL

为了使这更容易一些,让我们重新排列 WHERE 子句以根据它们的关系对 table 进行排序:

FROM BOM_CHILDS C
 , XX_MAIN.XX_MAST MAST
 , XX_MAIN.XX_STPO STPO
-- Joining C to MAST
WHERE C.MATNR = MAST.MATNR(+)
  AND C.WERKS = MAST.WERKS(+)
  AND MAST.STLAN(+) = '1'
-- Joining MAST to STPO
  AND MAST.STLNR = STPO.STLNR(+)
  AND STPO.IDNRK IS NULL

我们使用 C 作为 "driver" table 加入 CMAST 并从匹配的 MAST 中获取数据(左连接):

FROM BOM_CHILDS C
LEFT JOIN XX_MAIN.XX_MAST MAST
  ON C.MANTR = MAST.MANTR
 AND C.WERKS = MAST.WERKS
 AND MAST.STLAN = '1'

然后我们需要将 STPO 添加到连接中:

LEFT JOIN XX_MAIN.XX_STPO STPO
  ON MAST.STLNR = STPO.STLNR
 AND STPO.IDNRK IS NULL

将它们放在一起我们得到:

FROM BOM_CHILDS C
LEFT JOIN XX_MAIN.XX_MAST MAST
  ON C.MANTR = MAST.MANTR
 AND C.WERKS = MAST.WERKS
 AND MAST.STLAN = '1'
LEFT JOIN XX_MAIN.XX_STPO STPO
  ON MAST.STLNR = STPO.STLNR
 AND STPO.IDNRK IS NULL

就是说,即使 (+) 适用于 left/right/outer 加入,Oracle recommends not using it:

Oracle recommends that you use the FROM clause OUTER JOIN syntax rather than the Oracle join operator. Outer join queries that use the Oracle join operator (+) are subject to the following rules and restrictions, which do not apply to the FROM clause OUTER JOIN syntax: ...