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 加入 C
到 MAST
并从匹配的 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: ...
这是关于将查询转换为 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 加入 C
到 MAST
并从匹配的 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
clauseOUTER 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 theFROM
clauseOUTER JOIN
syntax: ...