我有以下数据
Order_ID Pallet_ID
O1 P1
O2 P1
O2 P2
O3 P2
O3 P3
O4 P4
订单可以在多个托盘上,托盘上可以有多个订单。我需要选择组成一组的订单组,因为它们共享同一组托盘。在上面的测试数据中,有两个这样的组{O1,O2,O3}和{O4},因为O1,O2和O3至少有一个托盘与该组的另一个成员共同。
现在我需要一些SQL来做这件事。我试过(greg_test包含上面的数据)
select distinct order_id
from greg_test
start with order_id = :order_id
connect by pallet_id = prior pallet_id
但是这给了我一个循环引用错误(用户数据中的ORA-01436 CONNECT BY循环)。添加nocycle没有给出正确的设置。
答案 0 :(得分:2)
此查询仅使用单个全表扫描,或者如果存在索引,则可以使用索引范围扫描。
select distinct order_id
from greg_test
start with order_id = :order_id
connect by nocycle pallet_id = prior pallet_id or order_id = prior order_id;
如果你使用11gR2,这将比上面的查询连接快一点,虽然语法是更奇怪的IMO。
with orders(order_id, pallet_id) as
(
select order_id, pallet_id
from greg_test
where order_id = :order_id
union all
select greg_test.order_id, greg_test.pallet_id
from greg_test
inner join orders
on greg_test.pallet_id = orders.pallet_id
or greg_test.pallet_id = orders.pallet_id
) cycle order_id, pallet_id set is_cycle to 'Y' default 'N'
select distinct order_id from orders;
如果您有大量数据,您需要彻底测试您使用的任何解决方案。分层查询通常会出现严重的性能问题。
答案 1 :(得分:1)
-- Z lists all order pairs that share a pallet, and also pairs each order with itself
WITH pairs AS (
-- all pairs of orders on the same pallet
SELECT DISTINCT a.order_id a, b.order_id b FROM greg_test a, greg_test b
WHERE a.pallet_id = b.pallet_id AND a.order_id != b.order_id
UNION ALL
-- pair all orders with themselves
SELECT DISTINCT order_id a, order_id b FROM greg_test
)
-- Now connect all the pairs
SELECT DISTINCT a FROM pairs
CONNECT BY NOCYCLE PRIOR a = b
START WITH a = :order_id
可能有一个更有效的解决方案。