Oracle中的wmsys.wm_concat主要實現行轉列功能(說白了就是將查詢的某一列值使用逗號進行隔開拼接,成為一條數據)。
wmsys.wm_concat除了單獨使用外還可以和over函數結合使用。
開始看看具體使用方法:
select t.rank, t.Name from t_menu_item t;
?? ?rank Name
????10 CLARK
????10 KING
????10 MILLER
????20 ADAMS
????20 FORD
????20 JONES
????20 SCOTT
????20 SMITH
????30 ALLEN
????30 BLAKE
????30 JAMES
????30 MARTIN
????30 TURNER
????30 WARD
上邊的查詢語句返回的結果可以清晰看到rank存在重復的,一個相同的rank對應多個Name,如果我們想把某一個Rank的所有Name以","隔開,怎么做的,當然可以自定義函數,
別急,Oracle 10g開始提供了這個wmsys.wm_concat,它可以幫助我們把行的值以逗號隔開,看看怎么來實現.
一。直接使用wmsys.wm_concat
select t.rank, WMSYS.WM_CONCAT(t.Name) TIME From t_menu_item t GROUP BY t.rank;
通過Group by進行分組,查詢每類Rank對應的Name的值,看看查詢的結果.
??? 10 CLARK, KING, MILLER
????20 ADAMS, FORD, JONES, SCOTT, SMITH
????30 ALLEN, BLAKE, JAMES, MARTIN, TURNER, WARD?
是不是很神奇,rank已經分類,并且他的Name已經用逗號進行隔開。
二.wmsys.wm_concat和over的結合使用
over函數:?over函數指定了分析函數工作的數據窗口的大小,這個數據窗口大小可能會隨著行的變化而變化。
例如:?
over(order by salary)按照salary排序進行累計,order by是個默認的開窗函數;
?over(partition by deptno) 按照部門分區;?
over(order by salary?range between 50 preceding and 150 following)每行對應的數據窗口是之前行幅度值不超過50,之后行幅度值不超過150的數據記錄 ;
over(order by salary rows between 50 perceding and 150 following)前50行,后150行;?
over(order by salary rows between unbounded preceding and unbounded following)所有行 ;
over(order by salary range between unbounded preceding and unbounded following)所有行。
看看wmsys.wm_concathe和over的結合例子:
select id,wmsys.wm_concat(name) over (order by id,name) name from idtable;
根據id,name進行排序累計,看看輸出的結果.
id name
??? ? ??10 ab
????????10 ab,bc
????????10 ab,bc,cd
????????20 ab,bc,cd,hi
????????20 ab,bc,cd,hi,ij
????????20 ab,bc,cd,hi,ij,mnke
可以清晰的看到id為10的name列的值是從ab依次疊加到最后ab,bc,cd(當然這幾個值肯定是id為10對應的值),id為20的name列的值是從ab,bc,cd,hi(之所以不是從ab開始是因為當前order by的
還有name列,所以需要繼續向下進行)一直到ab,bc,cd,hi,ij,mnke.
select id,wmsys.wm_concat(name) over (partition by id) name from idtable;
這個例子僅僅是根據id進行排序(over (order by ename)如果沒有order by 子句,求和就不是“連續”的,這個就是和上個實例的最大區別,沒有連續)。
?? ? ? ?ID NAME
????????10 ab,bc,cd
????????10 ab,bc,cd
????????10 ab,bc,cd
????????20 hi,ij,mn
????????20 hi,ij,mn
????????20 hi,ij,mn
可以看到僅僅是根據id進行排序的查詢。
select id,wmsys.wm_concat(name) over (partition by id,name) name from idtable;
????????ID NAME
????????10 ab
????????10 bc
????????10 cd
????????20 hi
????????20 ij
????????20 mn
可以看到,這里和上個實例的區別在于Name列沒有疊加,因為在over 中加入了name