使用臨時表 迴圈展 BOM

2021-04-14 11:18:50 字數 2542 閱讀 5496

背景

有如下的

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

all

select

'b',

'c'union

all

select

'c',

'd'union

all

select

'd',

'e'union

all

select

'd',

'f'union

all

select

'h',

'f'

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

child_part parent_part

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

cacb

dadb

eaeb

fafb

fh處理方法

一般可能會考慮從

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

-- 刪除臨時表

使用臨時表 迴圈展 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 in...