系列文章目錄
【SQL開發(fā)實戰(zhàn)技巧】系列(一):關(guān)于SQL不得不說的那些事
【SQL開發(fā)實戰(zhàn)技巧】系列(二):簡單單表查詢
【SQL開發(fā)實戰(zhàn)技巧】系列(三):SQL排序的那些事
【SQL開發(fā)實戰(zhàn)技巧】系列(四):從執(zhí)行計劃討論UNION ALL與空字符串&UNION與OR的使用注意事項
【SQL開發(fā)實戰(zhàn)技巧】系列(五):從執(zhí)行計劃看IN、EXISTS 和 INNER JOIN效率,我們要分場景不要死記網(wǎng)上結(jié)論
【SQL開發(fā)實戰(zhàn)技巧】系列(六):從執(zhí)行計劃看NOT IN、NOT EXISTS 和 LEFT JOIN效率,記住內(nèi)外關(guān)聯(lián)條件不要亂放
【SQL開發(fā)實戰(zhàn)技巧】系列(七):從有重復(fù)數(shù)據(jù)前提下如何比較出兩個表中的差異數(shù)據(jù)及對應(yīng)條數(shù)聊起
【SQL開發(fā)實戰(zhàn)技巧】系列(八):聊聊如何插入數(shù)據(jù)時比約束更靈活的限制數(shù)據(jù)插入以及怎么一個insert語句同時插入多張表
【SQL開發(fā)實戰(zhàn)技巧】系列(九):一個update誤把其他列數(shù)據(jù)更新成空了?Merge改寫update!給你五種刪除重復(fù)數(shù)據(jù)的寫法!
【SQL開發(fā)實戰(zhàn)技巧】系列(十):從拆分字符串、替換字符串以及統(tǒng)計字符串出現(xiàn)次數(shù)說起
【SQL開發(fā)實戰(zhàn)技巧】系列(十一):拿幾個案例講講translate|regexp_replace|listagg|wmsys.wm_concat|substr|regexp_substr常用函數(shù)
【SQL開發(fā)實戰(zhàn)技巧】系列(十二):三問(如何對字符串字母去重后按字母順序排列字符串?如何識別哪些字符串中包含數(shù)字?如何將分隔數(shù)據(jù)轉(zhuǎn)換為多值IN列表?)
【SQL開發(fā)實戰(zhàn)技巧】系列(十三):討論一下常用聚集函數(shù)&通過執(zhí)行計劃看sum()over()對員工工資進(jìn)行累加
【SQL開發(fā)實戰(zhàn)技巧】系列(十四):計算消費(fèi)后的余額&計算銀行流水累計和&計算各部門工資排名前三位的員工
【SQL開發(fā)實戰(zhàn)技巧】系列(十五):查找最值所在行數(shù)據(jù)信息及快速計算總和百之max/min() keep() over()、fisrt_value、last_value、ratio_to_report
【SQL開發(fā)實戰(zhàn)技巧】系列(十六):數(shù)據(jù)倉庫中時間類型操作(初級)日、月、年、時、分、秒之差及時間間隔計算
【SQL開發(fā)實戰(zhàn)技巧】系列(十七):數(shù)據(jù)倉庫中時間類型操作(初級)確定兩個日期之間的工作天數(shù)、計算—年中周內(nèi)各日期出現(xiàn)次數(shù)、確定當(dāng)前記錄和下一條記錄之間相差的天數(shù)
【SQL開發(fā)實戰(zhàn)技巧】系列(十八):數(shù)據(jù)倉庫中時間類型操作(進(jìn)階)INTERVAL、EXTRACT以及如何確定一年是否為閏年及周的計算
【SQL開發(fā)實戰(zhàn)技巧】系列(十九):數(shù)據(jù)倉庫中時間類型操作(進(jìn)階)如何一個SQL打印當(dāng)月或一年的日歷?如何確定某月內(nèi)第一個和最后—個周內(nèi)某天的日期?
【SQL開發(fā)實戰(zhàn)技巧】系列(二十):數(shù)據(jù)倉庫中時間類型操作(進(jìn)階)獲取季度開始結(jié)束時間以及如何統(tǒng)計非連續(xù)性時間的數(shù)據(jù)
【SQL開發(fā)實戰(zhàn)技巧】系列(二十一):數(shù)據(jù)倉庫中時間類型操作(進(jìn)階)識別重疊的日期范圍,按指定10分鐘時間間隔匯總數(shù)據(jù)
【SQL開發(fā)實戰(zhàn)技巧】系列(二十二):數(shù)倉報表場景? 從分析函數(shù)效率一定快嗎聊一聊結(jié)果集分頁和隔行抽樣實現(xiàn)方式
【SQL開發(fā)實戰(zhàn)技巧】系列(二十三):數(shù)倉報表場景? 如何對數(shù)據(jù)排列組合去重以及通過如何找到包含最大值和最小值的記錄這個問題再次用執(zhí)行計劃給你證明分析函數(shù)性能不一定高
【SQL開發(fā)實戰(zhàn)技巧】系列(二十四):數(shù)倉報表場景?通過案例執(zhí)行計劃詳解”行轉(zhuǎn)列”,”列轉(zhuǎn)行”是如何實現(xiàn)的
【SQL開發(fā)實戰(zhàn)技巧】系列(二十五):數(shù)倉報表場景?結(jié)果集中的重復(fù)數(shù)據(jù)只顯示一次以及計算部門薪資差異高效的寫法以及如何對數(shù)據(jù)進(jìn)行快速分組
【SQL開發(fā)實戰(zhàn)技巧】系列(二十六):數(shù)倉報表場景?聊聊ROLLUP、UNION ALL是如何分別做分組合計的以及如何識別哪些行是做匯總的結(jié)果行
【SQL開發(fā)實戰(zhàn)技巧】系列(二十七):數(shù)倉報表場景?通過對移動范圍進(jìn)行聚集來詳解分析函數(shù)開窗原理以及如何一個SQL打印九九乘法表
【SQL開發(fā)實戰(zhàn)技巧】系列(二十八):數(shù)倉報表場景?人員分布問題以及不同組(分區(qū))同時聚集如何實現(xiàn)
【SQL開發(fā)實戰(zhàn)技巧】系列(二十九):數(shù)倉報表場景?簡單的樹形(分層)查詢以及如何確定根節(jié)點(diǎn)、分支節(jié)點(diǎn)和葉子節(jié)點(diǎn)
【SQL開發(fā)實戰(zhàn)技巧】系列(三十):數(shù)倉報表場景?樹形(分層)查詢?nèi)绾闻判??以及如何在樹形查詢中正確的使用where條件
前言
本篇文章講解的主要內(nèi)容是:第一個案例給大家介紹在樹形(分層)查詢中,如何通過SIBLINGS關(guān)鍵詞進(jìn)行正確的排序。第二個案例主要介紹樹形查詢中的WHERE過濾的對象是"樹形查詢的結(jié)果"。這句話是重點(diǎn)?。。。?!所以要謹(jǐn)記,如果你有這種過濾+樹形查詢的需求,一定一定要先過濾,用子查詢嵌套一次,再進(jìn)行樹形查詢。
【SQL開發(fā)實戰(zhàn)技巧】這一系列博主當(dāng)作復(fù)習(xí)舊知識來進(jìn)行寫作,畢竟SQL開發(fā)在數(shù)據(jù)分析場景非常重要且基礎(chǔ),面試也會經(jīng)常問SQL開發(fā)和調(diào)優(yōu)經(jīng)驗,相信當(dāng)我寫完這一系列文章,也能再有所收獲,未來面對SQL面試也能游刃有余~。
一、樹形查詢中的排序
如果樹形查詢里直接使用ORDER BY
排序會怎樣?看下面的示例:
SELECT lpad('->', (level - 1) * 2, '->') || empno AS 員工編碼,
ename AS 姓名,
mgr AS 主管編碼,
(PRIOR ename) AS 主管姓名,
level as 級別,
decode(level, 1, 1) as 根節(jié)點(diǎn),
decode(connect_by_isleaf, 1, 1) as 葉子節(jié)點(diǎn),
CASE
WHEN (connect_by_isleaf = 0 AND LEVEL > 1) THEN
1
END AS 分支節(jié)點(diǎn),
sys_connect_by_path(ename,'->') as enames
FROM emp
START WITH empno = 7566
CONNECT BY (PRIOR empno) = mgr
order by empno;
員工編碼 姓名 主管編碼 主管姓名 級別 根節(jié)點(diǎn) 葉子節(jié)點(diǎn) 分支節(jié)點(diǎn) ENAMES
-------------------------------------------------------------------------------- ---------- ----- ---------- ---------- ---------- ---------- ---------- --------------------------------------------------------------------------------
->->7369 SMITH 7902 FORD 3 1 ->JONES->FORD->SMITH
7566 JONES 7839 1 1 ->JONES
->7788 SCOTT 7566 JONES 2 1 ->JONES->SCOTT
->->7876 ADAMS 7788 SCOTT 3 1 ->JONES->SCOTT->ADAMS
->7902 FORD 7566 JONES 2 1 ->JONES->FORD
從上面的結(jié)果可以看到,數(shù)據(jù)都亂了,上下級關(guān)系已經(jīng)完全亂了。而對于樹形數(shù)據(jù),我們需要的應(yīng)該是只對同一分支下的數(shù)據(jù)排序,此時就要用到專用關(guān)鍵字"SIBLINGS
":
SELECT lpad('->', (level - 1) * 2, '->') || empno AS 員工編碼,
ename AS 姓名,
mgr AS 主管編碼,
(PRIOR ename) AS 主管姓名,
level as 級別,
decode(level, 1, 1) as 根節(jié)點(diǎn),
decode(connect_by_isleaf, 1, 1) as 葉子節(jié)點(diǎn),
CASE
WHEN (connect_by_isleaf = 0 AND LEVEL > 1) THEN
1
END AS 分支節(jié)點(diǎn),
sys_connect_by_path(ename,'->') as enames
FROM emp
START WITH empno = 7566
CONNECT BY (PRIOR empno) = mgr
order siblings by empno;
員工編碼 姓名 主管編碼 主管姓名 級別 根節(jié)點(diǎn) 葉子節(jié)點(diǎn) 分支節(jié)點(diǎn) ENAMES
-------------------------------------------------------------------------------- ---------- ----- ---------- ---------- ---------- ---------- ---------- --------------------------------------------------------------------------------
7566 JONES 7839 1 1 ->JONES
->7788 SCOTT 7566 JONES 2 1 ->JONES->SCOTT
->->7876 ADAMS 7788 SCOTT 3 1 ->JONES->SCOTT->ADAMS
->7902 FORD 7566 JONES 2 1 ->JONES->FORD
->->7369 SMITH 7902 FORD 3 1 ->JONES->FORD->SMITH
可以看到,這個語句只對同一分支empno = 7566
的(7788,7902)進(jìn)行排序,而沒有影響到樹形結(jié)構(gòu)。
二、如何在樹形查詢中正確的添加WHERE條件
現(xiàn)在有個需求:如果限定只對部門20的人員進(jìn)行樹形查詢?
怎么做呢?估計很多人會直接在WHERe后加條件,如下:
SELECTempnoAS員工編碼,mgr AS主管編碼,enarneAS姓名,deptnoAS部門編碼
FROMemp
WHEREdeptno=20
STARTWITHmgrISNULL
CONNECTBY(PRIORempno)=mgr;
SELECT lpad('->', (level - 1) * 2, '->') || empno AS 員工編碼,
ename AS 姓名,
mgr AS 主管編碼,
(PRIOR ename) AS 主管姓名,
level as 級別,
decode(level, 1, 1) as 根節(jié)點(diǎn),
decode(connect_by_isleaf, 1, 1) as 葉子節(jié)點(diǎn),
CASE
WHEN (connect_by_isleaf = 0 AND LEVEL > 1) THEN
1
END AS 分支節(jié)點(diǎn),
deptno as 部門編碼,
sys_connect_by_path(ename,'->') as enames
FROM emp
where deptno=20
START WITH mgr is null
CONNECT BY (PRIOR empno) = mgr
order siblings by empno;
員工編碼 姓名 主管編碼 主管姓名 級別 根節(jié)點(diǎn) 葉子節(jié)點(diǎn) 分支節(jié)點(diǎn) 部門編碼 ENAMES
-------------------------------------------------------------------------------- ---------- ----- ---------- ---------- ---------- ---------- ---------- ---- --------------------------------------------------------------------------------
->7566 JONES 7839 KING 2 1 20 ->KING->JONES
->->7788 SCOTT 7566 JONES 3 1 20 ->KING->JONES->SCOTT
->->->7876 ADAMS 7788 SCOTT 4 1 20 ->KING->JONES->SCOTT->ADAMS
->->7902 FORD 7566 JONES 3 1 20 ->KING->JONES->FORD
->->->7369 SMITH 7902 FORD 4 1 20 ->KING->JONES->FORD->SMITH
SQL>
上面的結(jié)果咱們先不分析,我們先回頭看看emp表原來數(shù)據(jù)是什么樣的:
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980-12-17 800.00 20
7499 ALLEN SALESMAN 7698 1981-2-20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981-2-22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981-4-2 2975.00 20
7654 MARTIN SALESMAN 7698 1981-9-28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981-5-1 2850.00 30
7782 CLARK MANAGER 7839 1981-6-9 2450.00 10
7788 SCOTT ANALYST 7566 1987-4-19 3000.00 20
7839 KING PRESIDENT 1981-11-17 5000.00 10
7844 TURNER SALESMAN 7698 1981-9-8 1500.00 0.00 30
7876 ADAMS CLERK 7788 1987-5-23 1100.00 20
7900 JAMES CLERK 7698 1981-12-3 950.00 30
7902 FORD ANALYST 7566 1981-12-3 3000.00 20
7934 MILLER CLERK 7782 1982-1-23 1300.00 10
14 rows selected
從上面emp表數(shù)據(jù)我們可以看到,deptno=20
的員工中,壓根就沒有 mgr is null
的數(shù)據(jù),那根節(jié)點(diǎn)條件都為“假”,那哪來的樹形結(jié)構(gòu)?
所以說前面的樹形查詢這個結(jié)果明顯不對,因為部門20不存在mgr為空的數(shù)據(jù),那么也就不該返回數(shù)據(jù)。
下面我將emp表先進(jìn)行where deptno = 20
的過濾,然后在進(jìn)行樹形結(jié)構(gòu)的查詢??聪旅娴牟樵兘Y(jié)果,然后與上面的查詢做個對比:
SQL> SELECT lpad('->', (level - 1) * 2, '->') || empno AS 員工編碼,
2 ename AS 姓名,
3 mgr AS 主管編碼,
4 (PRIOR ename) AS 主管姓名,
5 level as 級別,
6 decode(level, 1, 1) as 根節(jié)點(diǎn),
7 decode(connect_by_isleaf, 1, 1) as 葉子節(jié)點(diǎn),
8 CASE
9 WHEN (connect_by_isleaf = 0 AND LEVEL > 1) THEN
10 1
11 END AS 分支節(jié)點(diǎn),
12 deptno as 部門編碼,
13 sys_connect_by_path(ename, '->') as enames
14 FROM (select * from emp where deptno = 20)
15 START WITH mgr is null
16 CONNECT BY (PRIOR empno) = mgr
17 order siblings by empno;
員工編碼 姓名 主管編碼 主管姓名 級別 根節(jié)點(diǎn) 葉子節(jié)點(diǎn) 分支節(jié)點(diǎn) 部門編碼 ENAMES
-------------------------------------------------------------------------------- ---------- ----- ---------- ---------- ---------- ---------- ---------- ---- --------------------------------------------------------------------------------
SQL>
這個語句沒有返回數(shù)據(jù)。原因是樹形查詢中的WHERE過濾的對象是"樹形查詢的結(jié)果"。這句話是重點(diǎn)!?。。?!所以要謹(jǐn)記,如果你有這種過濾+樹形查詢的需求,一定一定要先過濾,用子查詢嵌套一次,再進(jìn)行樹形查詢。文章來源:http://www.zghlxwxcb.cn/news/detail-407958.html
總結(jié)
本篇文章講解的主要內(nèi)容是:第一個案例給大家介紹在樹形(分層)查詢中,如何通過SIBLINGS關(guān)鍵詞進(jìn)行正確的排序。第二個案例主要介紹樹形查詢中的WHERE過濾的對象是"樹形查詢的結(jié)果"。這句話是重點(diǎn)?。。。。∷砸?jǐn)記,如果你有這種過濾+樹形查詢的需求,一定一定要先過濾,用子查詢嵌套一次,再進(jìn)行樹形查詢。文章來源地址http://www.zghlxwxcb.cn/news/detail-407958.html
到了這里,關(guān)于【SQL開發(fā)實戰(zhàn)技巧】系列(三十):數(shù)倉報表場景?樹形(分層)查詢?nèi)绾闻判颍恳约叭绾卧跇湫尾樵冎姓_的使用where條件的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!