Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Beim Ausführen einer rekursiven Abfrage wurde ein Zyklus erkannt

Im rekursiven Mitglied treten Sie derzeit nur bei a.product_id = b.product_id bei , statt a.order_id = b.order_id AND a.product_id = b.product_id; was hier nicht direkt von Bedeutung ist, würde es aber tun, wenn verschiedene Bestellungen dieselben Produkte enthalten würden, was in der realen Welt wahrscheinlich ist.

Ihre Daten und Abfragen scheinen jedoch keinen Zyklus zu haben. Sie scheinen über einen scheinbaren Fehler bei ANSI-Joins zu stolpern; Hinzufügen eines cycle -Klausel zeigt wie erwartet keine zyklischen Zeilen - und lässt es funktionieren!; und es funktioniert mit Joins im alten Stil:

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;

db<>fiddle

Sie müssen jedoch überhaupt nicht beitreten; Sie können Folgendes tun:

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;

die im final select die feste 1 Menge zuweist, oder:

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;

die es intern zuweist und die ursprüngliche Menge als neuen Alias ​​verfolgen muss.

Bei beiden habe ich das + 1 entfernt vom Mengenvergleich, da es dadurch zu früh aufhörte; mit einem order by hinzugefügt, erhalten beide:

ORDER_ID PRODUKT_ID MENGE
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

db<>fiddle