导航

    <#CACHE_INCLUDE_NAVBAR#>
« 分享HP HP0-P20 題庫Linux下查看軟、硬raid信息的方法 »

用SQL語句求排除斷號的號碼串

2011年1月5日 Linux 0条评论 0个引用

壹用戶對繳款日報中的票據號使用情況提出要求,希望以類似5-6,9-10,12-20的方式展現,以便直觀地反映實際使用的票據號情況。

  我們經過分析發現,實現這壹需求的難點主要有兩點:

  1. 如果要找出斷號,用SQL語句實現,主要是要考慮性能;

  2. 將排除斷後的使用號碼段的多條記錄轉換為壹行顯示,即用SQL實現行列轉換;

  如果通過編程來實現,這兩點都不難,但通過SQL來實現,則需要壹些技巧。

  假設知道已用票據號為3,4,5,7,8,11,12,最小為3,最大為12,求斷號的SQL如下:

  Select Rownum + (3 - 1)

  From Dual

  Connect By Rownum <= 12 - (3 - 1)

  Minus

  Select Column_Value Txt From Table(Cast(Zltools.f_Num2list('3,4,5,7,8,11,12') As Zltools.t_Numlist))

  求出的結果是三條記錄,6,9,10

  其中用到壹個技巧就是用Connect by Rownum來產生按順序增長的記錄集。

  求轉換為壹行顯示的已用票據段的SQL如下:

  With TEST As(

  Select Column_Value 編號 From Table(Cast(Zltools.f_Num2list('3,4,5,7,8,11,12') As Zltools.t_Numlist))

  )

  Select Substr(Max(LPAD(Length(分段), 5,'0') || 分段), 7, 1000) As 分段

  From (

  Select Sys_Connect_By_Path(分段, ',') As 分段

  From (

  Select Rownum As 行號,A.起始號||'-'||(B.中斷號-1) As 分段

  From (

  Select Rownum As 行號,編號 As 起始號

  From (

  Select 編號 From TEST

  Minus

  Select 編號+1 From TEST)

  ) A,

  (Select Rownum As 行號,編號 As 中斷號 From (

  Select 編號+1 As 編號 From TEST

  Minus

  Select 編號 From TEST)

  ) B

  Where A.行號=B.行號)

  Start With 行號 = 1

  Connect By (行號-1) = Prior 行號)

  查詢結果: 3-5,7-8,11-12

  其中用到以下技巧:

  1. 用minus方式求已用號碼段的起始號和終止號的記錄集

  2. 用Sys_Connect_By_Path函數和樹型查詢實現多行記錄轉換為壹列

  3. 用Substr,Max,LPAD,Length幾個函數的組合來求最長的壹條記錄

  如是Oracle 10G及以後的版本,可以使用壹個新的函數Wmsys.Wm_Concat,比前面樹型查詢的速度要快很多。

  With TEST As(

  Select Column_Value 編號 From Table(Cast(Zltools.f_Num2list('3,4,5,7,8,11,12') As Zltools.t_Numlist))

  )

  Select Wmsys.Wm_Concat(分段) as 分段

  From (

  Select Rownum As 行號,A.起始號||'-'||(B.中斷號-1) As 分段

  From (

  Select Rownum As 行號,編號 As 起始號

  From (

  Select 編號 From TEST

  Minus

  Select 編號+1 From TEST)

  ) A,

  (Select Rownum As 行號,編號 As 中斷號 From (

  Select 編號+1 As 編號 From TEST

  Minus

  Select 編號 From TEST)

  ) B

  Where A.行號=B.行號)

 

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最近发表

Powered By Z-Blog 1.8 Arwen Build 81206