执行递归查询时检测到循环
Cycle detected while executing recursive query
我正在使用 CTE 递归查询来获得低于输出但不知道为什么会这样
抛出“执行递归 WITH 查询时检测到的循环”。谁能告诉我我的查询哪里出了问题?
我的查询:
WITH
cte (order_id,
product_id,
quantity,
cnt)
AS
(SELECT order_id,
product_id,
1 as quantity,
1 as cnt
FROM order_tbl2
UNION ALL
SELECT a.order_id,
a.product_id,
b.quantity,
b.cnt + 1
FROM order_tbl2 A INNER JOIN cte b ON a.product_id = b.product_id
WHERE b.cnt + 1 < a.quantity)
SELECT order_id, product_id, 数量
来自 cte;
table/data 脚本:
CREATE TABLE ORDER_TBL2
(
ORDER_PAY DATE,
ORDER_ID VARCHAR2(10 BYTE),
PRODUCT_ID VARCHAR2(10 BYTE),
QUANTITY NUMBER(5),
PRICE NUMBER(5)
);
Insert into ORDER_TBL2
(ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
Values
(TO_DATE('5/1/2015', 'MM/DD/YYYY'), 'ORD1', 'PROD1', 5, 5);
Insert into ORDER_TBL2
(ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
Values
(TO_DATE('5/1/2015', 'MM/DD/YYYY'), 'ORD2', 'PROD2', 2, 10);
Insert into ORDER_TBL2
(ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
Values
(TO_DATE('5/1/2015', 'MM/DD/YYYY'), 'ORD3', 'PROD3', 3, 25);
COMMIT;
我认为您正在尝试扩展行。如果是这样,则不需要 join
:
WITH cte (order_id, product_id, quantity, cnt) AS (
SELECT order_id, product_id, quantity, 1 as cnt
FROM order_tbl2
UNION ALL
SELECT order_id, product_id, quantity, cnt + 1
FROM cte
WHERE cnt < a.quantity
)
SELECT *
FROM cte;
在递归成员中,您目前仅在 a.product_id = b.product_id
而不是 a.order_id = b.order_id AND a.product_id = b.product_id
加入;这在这里并不直接重要,但如果不同的订单包含相同的产品,这在现实世界中很可能会发生。
您的数据和查询实际上似乎没有循环。您似乎被 ANSI 连接的错误绊倒了;添加 cycle
子句不会像预期的那样显示任何循环行 - 并使其起作用!;它适用于旧式连接:
WITH
cte (order_id,
product_id,
quantity,
cnt)
AS
(SELECT order_id,
product_id,
1 as quantity,
1 as cnt
FROM order_tbl2
UNION ALL
SELECT a.order_id,
a.product_id,
b.quantity,
b.cnt + 1
FROM order_tbl2 A, cte b
WHERE b.cnt + 1 < a.quantity
AND a.order_id = b.order_id
AND a.product_id = b.product_id
)
SELECT order_id, product_id, quantity
FROM cte;
虽然您根本不需要加入;你可以这样做:
WITH
cte (order_id,
product_id,
quantity,
cnt)
AS
(SELECT order_id,
product_id,
quantity,
1 as cnt
FROM order_tbl2
UNION ALL
SELECT b.order_id,
b.product_id,
b.quantity,
b.cnt + 1
FROM cte b
WHERE b.cnt < b.quantity)
SELECT order_id, product_id, 1 as quantity
FROM cte;
在最后select中分配固定的1个数量,或者:
WITH
cte (order_id,
product_id,
real_quantity,
quantity,
cnt)
AS
(SELECT order_id,
product_id,
quantity as real_quantity,
1 as quantity,
1 as cnt
FROM order_tbl2
UNION ALL
SELECT b.order_id,
b.product_id,
b.real_quantity,
b.quantity,
b.cnt + 1
FROM cte b
WHERE b.cnt < b.real_quantity)
SELECT order_id, product_id, quantity
FROM cte;
在里面赋值,需要跟踪原始数量作为新的别名。
对于这两个,我都从数量比较中删除了 + 1
,因为那会使它停止得太早;添加 order by
,他们都得到:
ORDER_ID
PRODUCT_ID
QUANTITY
ORD1
PROD1
1
ORD1
PROD1
1
ORD1
PROD1
1
ORD1
PROD1
1
ORD1
PROD1
1
ORD2
PROD2
1
ORD2
PROD2
1
ORD3
PROD3
1
ORD3
PROD3
1
ORD3
PROD3
1
我正在使用 CTE 递归查询来获得低于输出但不知道为什么会这样 抛出“执行递归 WITH 查询时检测到的循环”。谁能告诉我我的查询哪里出了问题?
我的查询:
WITH
cte (order_id,
product_id,
quantity,
cnt)
AS
(SELECT order_id,
product_id,
1 as quantity,
1 as cnt
FROM order_tbl2
UNION ALL
SELECT a.order_id,
a.product_id,
b.quantity,
b.cnt + 1
FROM order_tbl2 A INNER JOIN cte b ON a.product_id = b.product_id
WHERE b.cnt + 1 < a.quantity)
SELECT order_id, product_id, 数量 来自 cte;
table/data 脚本:
CREATE TABLE ORDER_TBL2
(
ORDER_PAY DATE,
ORDER_ID VARCHAR2(10 BYTE),
PRODUCT_ID VARCHAR2(10 BYTE),
QUANTITY NUMBER(5),
PRICE NUMBER(5)
);
Insert into ORDER_TBL2
(ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
Values
(TO_DATE('5/1/2015', 'MM/DD/YYYY'), 'ORD1', 'PROD1', 5, 5);
Insert into ORDER_TBL2
(ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
Values
(TO_DATE('5/1/2015', 'MM/DD/YYYY'), 'ORD2', 'PROD2', 2, 10);
Insert into ORDER_TBL2
(ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
Values
(TO_DATE('5/1/2015', 'MM/DD/YYYY'), 'ORD3', 'PROD3', 3, 25);
COMMIT;
我认为您正在尝试扩展行。如果是这样,则不需要 join
:
WITH cte (order_id, product_id, quantity, cnt) AS (
SELECT order_id, product_id, quantity, 1 as cnt
FROM order_tbl2
UNION ALL
SELECT order_id, product_id, quantity, cnt + 1
FROM cte
WHERE cnt < a.quantity
)
SELECT *
FROM cte;
在递归成员中,您目前仅在 a.product_id = b.product_id
而不是 a.order_id = b.order_id AND a.product_id = b.product_id
加入;这在这里并不直接重要,但如果不同的订单包含相同的产品,这在现实世界中很可能会发生。
您的数据和查询实际上似乎没有循环。您似乎被 ANSI 连接的错误绊倒了;添加 cycle
子句不会像预期的那样显示任何循环行 - 并使其起作用!;它适用于旧式连接:
WITH
cte (order_id,
product_id,
quantity,
cnt)
AS
(SELECT order_id,
product_id,
1 as quantity,
1 as cnt
FROM order_tbl2
UNION ALL
SELECT a.order_id,
a.product_id,
b.quantity,
b.cnt + 1
FROM order_tbl2 A, cte b
WHERE b.cnt + 1 < a.quantity
AND a.order_id = b.order_id
AND a.product_id = b.product_id
)
SELECT order_id, product_id, quantity
FROM cte;
虽然您根本不需要加入;你可以这样做:
WITH
cte (order_id,
product_id,
quantity,
cnt)
AS
(SELECT order_id,
product_id,
quantity,
1 as cnt
FROM order_tbl2
UNION ALL
SELECT b.order_id,
b.product_id,
b.quantity,
b.cnt + 1
FROM cte b
WHERE b.cnt < b.quantity)
SELECT order_id, product_id, 1 as quantity
FROM cte;
在最后select中分配固定的1个数量,或者:
WITH
cte (order_id,
product_id,
real_quantity,
quantity,
cnt)
AS
(SELECT order_id,
product_id,
quantity as real_quantity,
1 as quantity,
1 as cnt
FROM order_tbl2
UNION ALL
SELECT b.order_id,
b.product_id,
b.real_quantity,
b.quantity,
b.cnt + 1
FROM cte b
WHERE b.cnt < b.real_quantity)
SELECT order_id, product_id, quantity
FROM cte;
在里面赋值,需要跟踪原始数量作为新的别名。
对于这两个,我都从数量比较中删除了 + 1
,因为那会使它停止得太早;添加 order by
,他们都得到:
ORDER_ID | PRODUCT_ID | QUANTITY |
---|---|---|
ORD1 | PROD1 | 1 |
ORD1 | PROD1 | 1 |
ORD1 | PROD1 | 1 |
ORD1 | PROD1 | 1 |
ORD1 | PROD1 | 1 |
ORD2 | PROD2 | 1 |
ORD2 | PROD2 | 1 |
ORD3 | PROD3 | 1 |
ORD3 | PROD3 | 1 |
ORD3 | PROD3 | 1 |