oracle遞歸查詢 start with connect by prior

(1)創建表結構

-- Create table
createtable TB_DW_JBXX
(
  dwid    CHAR(10) notnull,
  dwmc    VARCHAR2(100) notnull,
  tcq     CHAR(2) notnull,
  dwlx    CHAR(2) notnull,
  dj      NUMBER(3) notnull,
  yxzt    CHAR(1) notnull,
  lsdwid  CHAR(10) notnull,
  dwid_dxt CHAR(10)
)
tablespace DATA
  pctfree10
  initrans1
  maxtrans255
  storage
  (
    initial64K
    minextents1
    maxextentsunlimited
  );
-- Add comments to thecolumns
commentoncolumn TB_DW_JBXX.dwid is'單位ID';
commentoncolumn TB_DW_JBXX.dwmc  is'單位名稱';
commentoncolumn TB_DW_JBXX.tcq  is'所屬統籌區';
commentoncolumn TB_DW_JBXX.dwlx  is'單位類型';
commentoncolumn TB_DW_JBXX.dj
  is'單位等級 0:路局;1:社保中心;2......n:基層單位';
commentoncolumn TB_DW_JBXX.yxzt is'有效狀態 0:有效;1:無效';
commentoncolumn TB_DW_JBXX.lsdwid is'隸屬的上層單位';
commentoncolumn TB_DW_JBXX.dwid_dxt is'單位ID_大系統';
-- Create/Recreateprimary, unique and foreign key constraints
altertable TB_DW_JBXX
  addconstraint PK_TB_DW_JBXX primarykey (DWID)
  usingindex
  tablespace INDX
  pctfree10
  initrans2
  maxtrans255
  storage
  (
    initial64K
    minextents1
    maxextentsunlimited
  );
-- Grant/Revoke objectprivileges
grantselecton TB_DW_JBXX toGUEST_XX;


(2)插入數據,略

樹結構:

 

(3)語法說明

connect by 是結構化查詢中用到的,其基本語法是:
select … from tablename

where 條件3

start with 條件1
connect by 條件2;

   

條件1 是根結點的限定語句,當然可以放寬限定條件,以取得多個根結點,實際就是多棵樹。

條件2 是連接條件,其中用PRIOR表示上一條記錄
條件3 是過濾條件,用於對返回的所有記錄進行過濾

 

start with 子句:遍歷起始條件,

START WITH 可以省略:不指定樹的根,默認把Tree整個表中的數據從頭到尾遍歷一次,每一個數據做一次根,然後遍歷樹中其他節點信息.

connect by 子句:連接條件。STARTWITH 與CONNECT BY PRIOR位置可互換

 

關鍵詞prior

  prior跟父節點列lsdwid放在一起,就是往父結點方向遍歷;

  prior跟子結點列dwid放在一起,則往葉子結點方向遍歷,

  lsdwid、dwid兩列,誰放在“=”前都無所謂,關鍵是prior跟誰在一起。

  prior位置決定了檢索是自底向上還是自頂向下

  "prior" 如果缺省:則只能查詢到符合條件的起始行,並不進行遞歸查詢。 

orderby 子句:排序,不用多說。

 

(4)測試

--0900000002(上海) /0900000001 (全局)

--用例(1)

SELECT * FROM tb_dw_jbxx d WHERE d.yxzt='0' START WITH d.dwid='0900000002'CONNECT BY PRIOR d.dwid=d.lsdwid;
SELECT * FROM tb_dw_jbxx d WHERE d.yxzt='0' START WITH d.dwid='0900000002'CONNECT BY d.lsdwid= PRIOR d.dwid;

以上sql語句查詢結果是一樣的。結果如下:


數據分析:

123條數據,(包含當前節點數據)自頂向下、向子節點方向遍歷。

如果想獲取當前節點的所有子節點(不包含當前節點),可以直接取lsdwid這列數據。或使用用例(2)語句。

"prior" 如果缺省:則只能查詢到符合條件的起始行,並不進行遞歸查詢。 

SELECT * FROM tb_dw_jbxx d WHERE d.yxzt='0' START WITH d.dwid='0900000002' CONNECT BY  d.dwid=d.lsdwid;

數據結果略。

 

--用例(2)

SELECT * FROMtb_dw_jbxx d WHERE d.yxzt='0' START WITH d.lsdwid='0900000002' CONNECT BY PRIORd.dwid=d.lsdwid;

結果數據如下所示:


數據分析:

122條數據,(不包含當前節點數據)自頂向下、向子節點方向遍歷。

 

--用例(3)

SELECT * FROMtb_dw_jbxx d WHERE d.yxzt='0' START WITH d.dwid='0900000002' CONNECT BY  d.dwid= PRIOR d.lsdwid;

結果數據如下所示:


數據分析:

2條數據,(包含當前節點數據)自底向上、向子節點方向遍歷。

如果想獲取當前節點的所有父節點(不包含當前節點),可以直接取lsdwid這列數據。

--用例(4)

SELECT * FROMtb_dw_jbxx d WHERE /*d.yxzt='0' AND*/ d.lsdwid='0900000002' ;
SELECT * FROMtb_dw_jbxx d WHERE d.yxzt='0' START WITH d.lsdwid='0900000002' CONNECT BYd.dwid=  PRIOR d.lsdwid;

數據結果如下所示:


數據分析:

266條數據,(包含當前節點數據)自底向上、向子節點方向遍歷。

如果想獲取當前節點的所有父節點(不包含當前節點),可以直接取lsdwid這列數據。

'0900000002'下的一級子單位94條(SELECT * FROMtb_dw_jbxx d WHERE /*d.yxzt='0' AND*/ d.lsdwid='0900000002'),其中有效的78條,無效的16條。

266條數據中,94條全局的數據,94條上海的數據,78條子節點數據。

本來以爲會,78條全局的數據,78條上海的數據,78條子節點數據。

而實際數據卻是,94,94,78;

查詢原因:是16條無效的數據,也遞歸查詢父節點。

所以:where 語句,可以看成與遞歸查詢無關。只是對整個結果起過濾作用。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章