层次查询在展開Bom表中的應用。---Hierarchical Queries.

        在ERP系統中常常要用到BOM, 但如何展開一個BOM,是很多人很痛苦的一件事情,常常要寫一大堆的程序,其結果還是非常慢,通常跑出一個一階BOM出來要花幾個小時的時間。

        如果你的數據庫系統是 Oracle 8i,那麽你將不必再為這種事情煩惱,使用 Hierarchical Queries,你將輕而易主的展出一個BOM來。

上階展下階:
select
level lev,b.field01 father,b.field03 child,field07 base,field06,to_char(1||sys_connect_by_path(decode(trim(field10),'KPC',1000*field06,'KP',1000*field06,field06),'*')) total_usage,decode(trim(field10),'KPC','PC','KP','PC',field10) unit
from bom_table b start with field01='XX-XXXX-XX'
connect by prior field03=field01

下階找上階:
select
level lev,b.field01 father,b.field03 child,decode(trim(field10),'KPC',1000*field06,'KP',1000*field06,field06) usage,to_char(1||sys_connect_by_path(decode(trim(field10),'KPC',1000*field06,'KP',1000*field06,field06),'*')) total_usage,field07 base,decode(trim(field10),'KPC','PC','KP','PC',field10) unit
from bom_table b start with field03='YY-YYYY-YY'
connect by prior field01=field03

註釋一:  XX-XXXX-XX  需要展開的最上層成品料
           YY-YYYY-YY  需要展開的最下層元件料號 
           field01: 主件料件編號    field03 元件料件編號  field06 組成用量  field07 底數 field10 發料單位

註釋二: Sql中的Decode是為了統一單位.total_usage是最終的組成用量,其結果是一個以乘號表示的表達式,因爲無現成方法轉換,故最終還是需要在程式中進行結算。

以上为我在实际操作中的例子,以下为网友流方写的文章,表述更加清楚。仅做参考。

=================================================================================

http://blog.csdn.net/Drate/services/trackbacks/51233.aspx

最近收到网友一个问题,关于Oracle的层次查询的问题,发现Oracle 8i中一个非常有用的查询子句:
select level,rowid,...
  from ...
  where ...
  start with ...
  connect by expression;
语法说明:
*****************************************************
start with ...
connect by
(这是一个字句,不能拆开来写) 
语法的详细参考,请参考 ORACLE Release 8.0.5 Documentation Library中的 SELECT 帮助
文件位置 doc/database.804/a58225/ch4l.htm
简单说明:
start with ... connect by : 建立一个层次查询("Hierarchical Queries")
start with ... 子句:用户根记录的条件
connect by     子句:用于子记录合父记录的连接方式。是一个特定的条件表达式,必须为其中之一:
 PRIOR expr comparison_operator expr
 expr comparison_operator PRIOR expr

如果定义了start with... connect by子句,level就返回当前记录的层次号。
*****************************************************

这个语法通过定义一个cursor或视图就可以得到一个层次型的结果集,非常有用,特别是对于象生产企业的EBOM树的生成而言,
将明显改变BOM树生成的执行效率,因此,我将这个语法的内容做了分析:

给定这样的数据:
    DOC_PR  DOC_CH               TITLE                                  
--------- -------------------- -----------------------
      DOC   A                    A类                                     
        A   A2                   A-2                                     
        A   A3                   A-3                                     
        A   A1                   A-1                                     
       A1   A11                  A1-1                                    
      DOC   B                    B类                                     
        B   B1                   B-1                                     
        B   B2                   B-2                                     
        B   B3                   B-3                                     
       B3   B31                  B-3-1                                   
      DOC   C                    C类                                     
        C   C1                   test C1                                 
        
定义一个cursor
Declare curTree Cursor For              
 select level, doc_ch, title, rowid  
  from doc_tree                   
  start with doc_pr = 'DOC'   
  connect by doc_pr = Prior doc_ch;
  
返回结果集如下:
   LEVEL DOC_CH               TITLE                                    ROWID
-------- -------------------- ---------------------------------------- ------------------
       1 A                    A类                                      AAAAi+AADAAAAyNAAE
       2 A2                   A-2                                      AAAAi+AADAAAAyNAAM
       2 A3                   A-3                                      AAAAi+AADAAAAyNAAN
       2 A1                   A-1                                      AAAAi+AADAAAAyNAAP
       3 A11                  A1-1                                     AAAAi+AADAAAAyNAAS
       1 B                    B类                                      AAAAi+AADAAAAyNAAF
       2 B1                   B-1                                      AAAAi+AADAAAAyNAAO
       2 B2                   B-2                                      AAAAi+AADAAAAyNAAQ
       2 B3                   B-3                                      AAAAi+AADAAAAyNAAR
       3 B31                  B-3-1                                    AAAAi+AADAAAAyNAAB
       1 C                    C类                                      AAAAi+AADAAAAyNAAG
       2 C1                   test C1                                  AAAAi+AADAAAAyNAAC
         
这段语法的ORACLE内部逻辑我分析如下:
 选择 level,doc_ch,title,rowid
 从 doc_tree
 以 doc_pr = "DOC"开始
 用 doc_pr = 上一个结果的 doc_ch来连接
 
取出第一个结果集后, as_start自动转换为 当前行的 doc_ch,然后执行
select level, doc_ch, title, rowid
 from doc_tree where doc_pr = prior doc_ch 
这样循环本层次结果集,然后再开始下一个结果集的处理。
这是内部的逻辑,而返回给用户的是一个按层次完成的结果集


有了这样一个结果集,对于建立treeview是非常方便的,只要循环所有记录就可以轻松实现了。     

在Sybase,MS SQL Server中不知有没有这样的语法,我不是太清楚,如果您知道,请告诉我。

现在我在MS SQL Server中的实现是这样的:
加入字段level而不是伪列。实现原理同上面是一致的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值