递归WITH查询在oracle中如何工作?什么时候进入循环?
How does the recursive WITH query work in oracle? When does it go into a cycle?
我有一个场景,我必须根据其数量列中的值显示一行 'n' 次。
Item Qty
abc 2
cde 1
Item Qty
abc 1
abc 1
cde 1
我希望将第一个 table 转换为第二个。
我发现了我应该使用递归 WITH 查询的网站。
我的主播会员returns原table.
SELECT ITEM, QTY
FROM lines
WHERE
JOB = TO_NUMBER ('1')
AND ITEM IN
(SELECT PART
FROM PICK
WHERE DELIVERY = '2')
我的递归成员如下
SELECT CTE.ITEM, (CTE.QTY - 1) QTY
FROM CTE
INNER JOIN
(SELECT ITEM, QTY
FROM LINES
WHERE JOB_ID = TO_NUMBER ('1')
AND ITEM IN
(SELECT PART
FROM PICK
WHERE DELIVERY = '2'
)) T
ON CTE.ITEM = T.ITEM
WHERE CTE.QTY > 1
我的目标是先获取所有零件和数量,然后在递归步骤中为所有数量 > 1 的零件生成要添加到原始结果集中的新行,新行中显示的数量将是(该部分的原始数量 - 1)。递归将继续进行,直到所有部分的 qty 变为 1。
这就是我最后的结果。
WITH CTE (ITEM, QTY)
AS (
SELECT ITEM, QTY
FROM lines
WHERE
JOB = TO_NUMBER ('1')
AND ITEM IN
(SELECT PART
FROM PICK
WHERE DELIVERY = '2')
UNION ALL
SELECT CTE.ITEM, (CTE.QTY - 1) QTY
FROM CTE
INNER JOIN
(SELECT ITEM, QTY
FROM LINES
WHERE JOB_ID = TO_NUMBER ('1')
AND ITEM IN
(SELECT PART
FROM PICK
WHERE DELIVERY = '2'
)) T
ON CTE.ITEM = T.ITEM
WHERE CTE.QTY > 1)
SELECT ITEM, QTY
FROM CTE
ORDER BY 1, 2 DESC
当我尝试上述操作时出现以下错误
"ORA-32044: cycle detected while executing recursive WITH query"
怎么进入循环的?我在它的工作中错过了什么?
此外,如果我使用 "cycle clause" 从另一个网站阅读。我能够停止循环。
我使用的子句是。
CYCLE
QUANTITY
SET
END TO '1'
DEFAULT '0'
如果我在 select 语句之前使用它。我得到了想要的输出,但我觉得这不是正确的方法。子句到底在做什么?什么是正确的使用方法?
Oracle 设置:
CREATE TABLE lines ( Item, Qty ) AS
SELECT 'abc', 2 FROM DUAL UNION ALL
SELECT 'cde', 1 FROM DUAL;
CREATE TABLE pick ( part, delivery ) AS
SELECT 'abc', 2 FROM DUAL UNION ALL
SELECT 'cde', 2 FROM DUAL;
查询 1:使用分层查询:
SELECT Item,
COLUMN_VALUE AS qty
FROM lines l
CROSS JOIN
TABLE(
CAST(
MULTISET(
SELECT 1
FROM DUAL
CONNECT BY LEVEL <= l.Qty
)
AS SYS.ODCINUMBERLIST
)
) t
WHERE item IN ( SELECT part FROM pick WHERE delivery = 2 )
查询 2:使用递归子查询分解子句:
WITH rsqfc ( item, qty ) AS (
SELECT item, qty
FROM lines l
WHERE item IN ( SELECT part FROM pick WHERE delivery = 2 )
UNION ALL
SELECT item, qty - 1
FROM rsqfc
WHERE qty > 1
)
SELECT item, 1 AS qty
FROM rsqfc;
输出:
ITEM | QTY
:--- | --:
abc | 1
abc | 1
cde | 1
db<>fiddle here
我有一个场景,我必须根据其数量列中的值显示一行 'n' 次。
Item Qty
abc 2
cde 1
Item Qty
abc 1
abc 1
cde 1
我希望将第一个 table 转换为第二个。
我发现了我应该使用递归 WITH 查询的网站。
我的主播会员returns原table.
SELECT ITEM, QTY
FROM lines
WHERE
JOB = TO_NUMBER ('1')
AND ITEM IN
(SELECT PART
FROM PICK
WHERE DELIVERY = '2')
我的递归成员如下
SELECT CTE.ITEM, (CTE.QTY - 1) QTY
FROM CTE
INNER JOIN
(SELECT ITEM, QTY
FROM LINES
WHERE JOB_ID = TO_NUMBER ('1')
AND ITEM IN
(SELECT PART
FROM PICK
WHERE DELIVERY = '2'
)) T
ON CTE.ITEM = T.ITEM
WHERE CTE.QTY > 1
我的目标是先获取所有零件和数量,然后在递归步骤中为所有数量 > 1 的零件生成要添加到原始结果集中的新行,新行中显示的数量将是(该部分的原始数量 - 1)。递归将继续进行,直到所有部分的 qty 变为 1。
这就是我最后的结果。
WITH CTE (ITEM, QTY)
AS (
SELECT ITEM, QTY
FROM lines
WHERE
JOB = TO_NUMBER ('1')
AND ITEM IN
(SELECT PART
FROM PICK
WHERE DELIVERY = '2')
UNION ALL
SELECT CTE.ITEM, (CTE.QTY - 1) QTY
FROM CTE
INNER JOIN
(SELECT ITEM, QTY
FROM LINES
WHERE JOB_ID = TO_NUMBER ('1')
AND ITEM IN
(SELECT PART
FROM PICK
WHERE DELIVERY = '2'
)) T
ON CTE.ITEM = T.ITEM
WHERE CTE.QTY > 1)
SELECT ITEM, QTY
FROM CTE
ORDER BY 1, 2 DESC
当我尝试上述操作时出现以下错误 "ORA-32044: cycle detected while executing recursive WITH query"
怎么进入循环的?我在它的工作中错过了什么?
此外,如果我使用 "cycle clause" 从另一个网站阅读。我能够停止循环。
我使用的子句是。
CYCLE
QUANTITY
SET
END TO '1'
DEFAULT '0'
如果我在 select 语句之前使用它。我得到了想要的输出,但我觉得这不是正确的方法。子句到底在做什么?什么是正确的使用方法?
Oracle 设置:
CREATE TABLE lines ( Item, Qty ) AS
SELECT 'abc', 2 FROM DUAL UNION ALL
SELECT 'cde', 1 FROM DUAL;
CREATE TABLE pick ( part, delivery ) AS
SELECT 'abc', 2 FROM DUAL UNION ALL
SELECT 'cde', 2 FROM DUAL;
查询 1:使用分层查询:
SELECT Item,
COLUMN_VALUE AS qty
FROM lines l
CROSS JOIN
TABLE(
CAST(
MULTISET(
SELECT 1
FROM DUAL
CONNECT BY LEVEL <= l.Qty
)
AS SYS.ODCINUMBERLIST
)
) t
WHERE item IN ( SELECT part FROM pick WHERE delivery = 2 )
查询 2:使用递归子查询分解子句:
WITH rsqfc ( item, qty ) AS (
SELECT item, qty
FROM lines l
WHERE item IN ( SELECT part FROM pick WHERE delivery = 2 )
UNION ALL
SELECT item, qty - 1
FROM rsqfc
WHERE qty > 1
)
SELECT item, 1 AS qty
FROM rsqfc;
输出:
ITEM | QTY :--- | --: abc | 1 abc | 1 cde | 1
db<>fiddle here