<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Decode360's Blog

    業(yè)精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
      302 隨筆 :: 26 文章 :: 82 評(píng)論 :: 0 Trackbacks
    1、打印一張當(dāng)月的日歷:
    ?

    select max (decode( mod (n, 7 ), 0 , m, null )) ,

    ?????? max (decode( mod (n, 7 ), 1 , m, null )) ,

    ?????? max (decode( mod (n, 7 ), 2 , m, null )) ,

    ?????? max (decode( mod (n, 7 ), 3 , m, null )) ,

    ?????? max (decode( mod (n, 7 ), 4 , m, null )) ,

    ?????? max (decode( mod (n, 7 ), 5 , m, null )) ,

    ?????? max (decode( mod (n, 7 ), 6 , m, null ))

    ? from ( select rownum m, rownum + to_char(trunc( sysdate , 'mm' ), 'd' ) - 2 n

    ????????? from dual

    ??????? connect by rownum < = to_char(last_day( sysdate ), 'dd' ))

    ? group by trunc(n / 7 )

    ? order by trunc(n / 7 );

    ?

    說(shuō)明:

    1、首先通過(guò) connect by rownum < = to_char(last_day( sysdate ), 'dd' ) 來(lái)取出當(dāng)月的天數(shù)序列

    2、再用 to_char(trunc(sysdate, 'mm'), 'd')-2 來(lái)提取當(dāng)天是對(duì)應(yīng)星期幾

    3、通過(guò) decode( mod (n, 7 ), 0 , m, null ) 來(lái)確定該天打印在星期幾的列中,其實(shí)mod放到第2步做思路更加清晰

    4、通過(guò) group by trunc(n / 7 ) 來(lái)將一個(gè)星期內(nèi)的天數(shù)打印到一行中

    5、雖然比較簡(jiǎn)單,而且也沒(méi)有什么實(shí)用價(jià)值,不過(guò)這個(gè)小程序還是有一些閃光點(diǎn)的,比如group by,記錄一下

    ?

    ?

    ?

    2、用SQL直接取工作日:

    ?

    ?

    with t as ( select date '2008-09-01' s, date '2008-09-10' e from dual)

    select s,e,e-s+ 1 total_days,

    (length( replace (rpad(substr( '0111110' ,to_char(s, 'd' )),e-s+ 1 , '0111110' ), '0' , '' ))) work_days

    from t;

    ?

    說(shuō)明:

    1、其他沒(méi)什么好說(shuō)的,主要就是 (length( replace (rpad(substr( '0111110' ,to_char(s, 'd' )),e-s+ 1 , '0111110' ), '0' , '' ))) 這句了,一層層看一下

    2、substr('0111110',to_char(s,'d')) 這句的作用是找出開(kāi)始日為星期幾,并將其后的每一天對(duì)應(yīng)011110,0為休息日,1為工作日

    3、rpad(substr('0111110',to_char(s,'d')),e-s+1,'0111110') 將字符串填充的e-s+1的長(zhǎng)度,且每個(gè)工作日均對(duì)應(yīng)為1,休息日為0

    4、replace 的作用是把011111011111011111……中的0都刪除,留下1

    5、最后用length 統(tǒng)計(jì)一下字符串的長(zhǎng)度即為工作日的天數(shù)

    6、這個(gè)方法雖然簡(jiǎn)單,但是有一個(gè)很大的問(wèn)題,就是Oracle的字符串最長(zhǎng)只有4000個(gè)字符,也就是說(shuō),相隔時(shí)間大于4000天的,work_days 將恒等于2858而發(fā)生錯(cuò)誤,所以需要進(jìn)行進(jìn)一步的改進(jìn)

    ?

    ?

    with t as (selectdate'2008-09-01' s,date'2008-09-10' e from dual )

    select s,e,e-s+ 1 total_days,

    trunc((e-s+ 1 )/ 7 )* 5 + nvl(length( replace (substr( '01111100111110' ,to_char(s, 'd' ), mod (e-s+ 1 , 7 )), '0' , '' )), 0 ) work_days

    from t;

    ?

    說(shuō)明:

    1、使用了trunc((e-s+1)/7)*5的形式,然后進(jìn)行不整位的補(bǔ)足,就沒(méi)有了字符串長(zhǎng)度的限制

    2、當(dāng)(e-s+1)是7的倍數(shù)時(shí),顯然工作日就是 ((e-s+1)/7)*5

    3、當(dāng)(e-s+1)不被7整除是,可以理解為將最前面不能被7整除的部分mod(e-s+1,7)取出來(lái),剩余的部分則正好為((e-s+1)/7)*5

    4、nvl(length(replace(substr('01111100111110',to_char(s,'d'),mod(e-s+1,7)),'0','')),0)就是對(duì)mod(e-s+1,7)部分的操作

    5、接下來(lái)這部分跟前一種方法的原理差不多,就是根據(jù)起始位置是星期幾,來(lái)順次往后取到工作日標(biāo)記為1,休息日標(biāo)記為0

    6、需要注意的是substr('0111110',n,0)結(jié)果為null,replace('0','0','')的結(jié)果也為null,此時(shí)整個(gè)修正不為結(jié)果為null,無(wú)法正確顯示結(jié)果,好在這兩種情況下后面部分的結(jié)果都是可以忽略不記的,所以在最外面套一層nvl就可以了。




    ?





    -The End-

    posted on 2008-08-30 19:21 decode360-3 閱讀(134) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): SQL Dev
    主站蜘蛛池模板: 日本高清不卡中文字幕免费 | 四虎影视永久在线精品免费| 99久久免费国产香蕉麻豆| 亚洲精品成人av在线| 免费一级毛片在线播放视频| 久久久久久久综合日本亚洲 | 久99精品视频在线观看婷亚洲片国产一区一级在线| 亚洲一级片在线观看| 野花高清在线观看免费完整版中文 | 亚洲AV中文无码乱人伦在线视色 | 四虎亚洲国产成人久久精品| 免费播放国产性色生活片| 亚洲国产精品一区二区三区久久| 爱情岛论坛免费视频| 中文字幕亚洲天堂| 久久久久久久99精品免费观看| 亚洲AV无码一区东京热| 亚洲一区二区免费视频| 亚洲爆乳少妇无码激情| 亚洲精品tv久久久久久久久久| 精精国产www视频在线观看免费| 亚洲春色在线视频| 一二三四在线观看免费高清中文在线观看 | 亚洲精品亚洲人成在线播放| 热99re久久精品精品免费| 搜日本一区二区三区免费高清视频| 国产亚洲人成A在线V网站| 久爱免费观看在线网站| 亚洲制服在线观看| 免费国产a国产片高清| 国产一级黄片儿免费看| 亚洲综合久久成人69| 精品国产免费一区二区| 久久99精品免费一区二区| 亚洲短视频男人的影院| 在线免费观看视频你懂的| 国产精品美女久久久免费| 亚洲三级在线免费观看| 亚洲色偷偷狠狠综合网| 最近免费中文字幕大全高清大全1| 亚洲风情亚Aⅴ在线发布|