我有一个 SQL 表,其中特别包含 3 个感兴趣的列: 订单ID、原始订单ID、父订单ID
列的使用对于这个问题并不重要。尽管如此,OrderID 是订单的开始,而其他两个列则用于针对原始 Order-ID 的退款等。 OrderID 是 PK,而其他 2 列有自己的索引。
我编写了以下递归查询。目的是搜索订单 ID 并返回在上述 3 列中任意一列中包含该订单 ID 值的所有行。
显然,我希望脚本高效,只读取关联的行而不是表中的所有内容(我怀疑这可能正在发生)。
为了本文的目的,这里有一些示例数据:
declare @MyTable table (OrderID int, OriginalOrderID int, ParentOrderID int)
insert into @MyTable values
(437, 421, 436)
,(436, 420, null)
,(421, null, 420)
,(420, null, null)
话虽如此,这是我对 CTE 的尝试。 预先感谢您的见解和解释。
DECLARE @OrderIDs table (OrderId int, isParent bit)
-- ----------------------------\
-- Define the Order Id .. can be Original/Parent ID or Spawn/Child/Conversion ID:
DECLARE @SearchOrderID as int = 421
-- ----------------------------/
-- Build CTE to find all related (parent / child) OrderIDs:
;WITH Children as (
select o1.orderId
, o1.parentOrderId
, o1.originalOrderId
from @MyTable o1
where o1.orderId = @SearchOrderID
UNION ALL -- Add all rows from 1st query results to the subsequent recursive query's results
select o2.orderId
, o2.parentOrderId
, o2.originalOrderId
from @MyTable o2
inner join Children co on co.orderId = o2.originalOrderId
UNION ALL
select o3.orderId
, o3.originalOrderId
, o3.parentOrderId
from @MyTable o3
inner join Children co on co.orderId = o3.ParentOrderID
),
Original as (
select o1.orderId
, o1.originalOrderId
, o1.parentOrderId
from @MyTable o1
where o1.orderId = @SearchOrderID
UNION ALL
select o2.orderId
, o2.originalOrderId
, o2.parentOrderId
from @MyTable o2
inner join Original oo on oo.originalOrderId = o2.orderId
UNION ALL
select o3.orderId
, o3.originalOrderId
, o3.parentOrderId
from @MyTable o3
inner join Original oo on oo.OriginalOrderID = o3.ParentOrderID
),
Parents as (
select o1.orderId
, o1.originalOrderId
, o1.parentOrderId
from @MyTable o1
where o1.orderId = @SearchOrderID
UNION ALL
select o2.orderId
, o2.originalOrderId
, o2.parentOrderId
from @MyTable o2
inner join Parents po on po.ParentOrderId = o2.orderId
UNION ALL
select o3.orderId
, o3.originalOrderId
, o3.parentOrderId
from @MyTable o3
inner join Parents po on po.ParentOrderID = o3.OriginalOrderID
)
insert into @OrderIDs
select orderId, 0 from Children
UNION
select orderId, 0 from Original
UNION
select orderId, 0 from Parents
-- Show Parent / Child relationship:
select * from @OrderIDs
order by IsParent desc
这样不行吗?
declare @SearchOrderID as int = 420;
select * , case when @SearchOrderID=ParentOrderId then 1 else 0 end as IsParent
from @MyTable M
where OrderID in (select OrderId
from @MyTable
where @SearchOrderID in (OrderID, OriginalOrderID, ParentOrderID))