使用臨時表 迴圈展 BOM

2021-08-22 11:00:22 字數 2237 閱讀 7293

背景

有如下的bom 表,parent_part 與child_part 是多對多的關係,現在要求查詢出每個child_part 的最頂層的 parent_part

create

table pl_bom(

parent_part varchar

(10),

child_part varchar

(10))

insert

into pl_bom

select

'a',

'c'union

allselect

'b',

'c'union

allselect

'c',

'd'union

allselect

'd',

'e'union

allselect

'd',

'f'union

allselect

'h',

'f'

即根據上述資料,應該得到如下結果

child_part parent_part

---------- -----------

c ac b

d ad b

e ae b

f af b

f h

處理方法

一般可能會考慮從 child_part 開始掃瞄的方法。但對於每個child_part 而言,它有一至多個 parent_part,對於多個parent_part 而言,每個 parent_part 到最頂部的 parent_part 經過的層數還可能不一致,這會導致掃瞄演算法不太好寫,而且同乙個 parent_part 如果被多個 child_part 引用的話, 還可能導致重複的搜尋此 parent_part 的頂 parent_part。

下面的演算法採用自 parent_part 反推 child_part 的方式,可以避免重複掃瞄某個 parent_part 到 child_part 的問題

-- 使用自頂向下展開

-- 因為要刪除資料, 所以不能用原始表, 用個臨時表

select

id =

identity

(int

, 1,1 ), child_part, parent_part

into#

from

pl_bom

-- 從頂往下展

declare

@level int

set@level = 1

select

id = id * 1,

level

= @level,

child_part, parent_part

into

#re

from

# a

where

notexists(

select

*from #

where child_part = a.parent_part)

while

@@rowcount

> 0

begin

set @level = @level + 1

delete a

from # a, #re b

where a.id = b.id

and b.level = @level - 1

insert #re(

id,level

,child_part, parent_part)

select

a.id, @level,

a.child_part, b.parent_part

from # a, #re b

where a.parent_part = b.child_part

and b.level = @level - 1

end

-- 顯示結果

select

child_part, parent_part

from

#re

order

by 1, 2

-- 刪除臨時表

drop

table #re, #

使用臨時表 迴圈展 BOM

背景 有如下的 bom 表,parent part 與child part 是多對多的關係,現在要求查詢出每個 child part 的最頂層的 parent part create table pl bom parent part varchar 10 child part varchar 10 ...

使用臨時表 迴圈展 BOM

背景 有如下的 bom 表,parent part 與child part 是多對多的關係,現在要求查詢出每個 child part 的最頂層的 parent part create table pl bom parent part varchar 10 child part varchar 10 ...

使用臨時表 迴圈展 BOM

背景 有如下的 bom 表,parent part 與child part 是多對多的關係,現在要求查詢出每個 child part 的最頂層的 parent part create table pl bom parent part varchar 10 child part varchar 10 ...