【SQL】漢字のソート
よく考えてみたら今まで漢字のソートってやったことなかったぜ。
でもってずーと読み順でソートされるものだと思ってたけど、どうやら違うっぽい。
with east as(
select nm =’東幹久’ ,tm = ‘あずまみきひさ’ union all
select nm =’東国原秀夫’,tm = ‘ひがしこくばるひでお’ union all
select nm =’東野幸治’ ,tm = ‘ひがしのこうじ’union all
select nm =’東儀秀樹’ ,tm = ‘とうぎひでき’union all
select nm =’東海林のり子’,tm = ‘しょうじのりこ’
)
select * from east order by tm
■最近自分も学習したのだけど、with句には複数設定することが可能らしい↓
with t1 as( /*@SQL鯖2005 */
select rowid= 1,isbn = 4492042997 union all
select rowid= 2,isbn = 4774135380
),t2 as(
select isbn = 4492042997,bknm = ‘出逢いの大学’,authorid= ‘p1′ union all
select isbn = 4774135380,bknm = ‘小さなニュースに火をつけて売る!’,authorid=’p2′
),t3 as(
select authorid=’p1′,authorname = ‘千葉智之’ union all
select authorid=’p2′,authorname = ‘松本拓也’
)select rowid
, bookname = bknm
, isbncode = x.isbn
, author = authorname
from t1 x
left outer join t2 y
on x.isbn = y.isbn
left outer join t3 z
on y.authorid = z.authorid
※select文の結果↓

(続きを読む…)
with test as( — @SQL Server2005
select hoge = 20 union all
select hoge = 10 union all
select hoge = 50 union all
select hoge = 0 union all
select hoge = 100
)
select ex1 = avg(hoge)
, ex2 = avg(case when hoge = 0 then null else hoge end)
from test
ex1:( 20 + 10 + 50 + 0 + 100 ) / 5
ex2:( 20 + 10 + 50 + 100 ) / 4
...移動平均を求める場合、例えば25日すべてに株価の値がつくとは限らないので、そういう場合は0をnullに置き換えた上でAVG関数を利用してやれば値が付かなかったレコードも上手に平均値が算出可能のようです。
with tbl as( /* @SQL Server */
select code
, nm = RANK() OVER (PARTITION BY code ORDER BY period DESC)
, period
, price
from (
select code= 1301 , period = 20080430,Price= 10 union all
select code= 1301 , period = 20080501,Price= 20 union all
select code= 1301 , period = 20080502,Price= 30 union all
select code= 1301 , period = 20080507,Price= 40 union all
select code= 1301 , period = 20080508,Price= 50 union all
select code= 1301 , period = 20080509,Price= 60 union all
select code= 1301 , period = 20080512,Price= 70 union all
select code= 1301 , period = 20080513,Price= 80 union all
select code= 1301 , period = 20080514,Price= 90 union all
select code= 7203 , period = 20080501,Price= 11 union all
select code= 7203 , period = 20080502,Price= 22 union all
select code= 7203 , period = 20080507,Price= 33 union all
select code= 7203 , period = 20080508,Price= 44 union all
select code= 7203 , period = 20080509,Price= 55 union all
select code= 7203 , period = 20080512,Price= 66 union all
select code= 7203 , period = 20080513,Price= 77 union all
select code= 7203 , period = 20080514,Price= 88 union all
select code= 7203 , period = 20080515,Price= 99
) x
)select a.code
, a.nm
, a.period
, a.price
, MovingAverage=avg(b.price)
/*
, a.period
, a.price
, b.nm
, b.period
, b.price
*/
from tbl a
cross join tbl b
where a.code= b.code
and a.nm+5 > b.nm
and a.nm <= b.nm
group by a.code
, a.nm
, a.period
, a.price
having count(*)=5
order by a.code
, a.nm desc
その3の続き
ていうかナンバリング番号を格納したnum列をもう一回Over句でリナンバリングし直すということもSQL Server2005ならば可能だと、さっきふと思った。
with test_Table as(
select num = 2 ,code = 2121,Period =200503 union all
select num = 3 ,code = 2121,Period =200603 union all
select num = 4 ,code = 2121,Period =200703 union all
select num = 3 ,code = 7203,Period =200303 union all
select num = 4 ,code = 7203,Period =200403 union all
select num = 5 ,code = 7203,Period =200503 union all
select num = 6 ,code = 7203,Period =200603 union all
select num = 7 ,code = 7203,Period =200703
)
select code
, period
, num
, num1 = rank() over(partition by code order by num)
, num2 = rank() over(order by code,num)
from test_Table
order by code,num
最大公約数とかって意外と時間も我も忘れてのめり込んでしまい、他業務に支障をきたすので超危険っす。結局今日のところはお手軽ループ文で余りがゼロにならないまで割り算していくロジックで逃げたのですが、ううっ、Oリーダー、ごめんなさいorz
その2からの続き
SQL Server2005から、順位付け関数(Over句)が用意されているので、これを利用すれば何も自己結合でゴキンゴキンにややこしいjoinなんかしなくても超簡単にリナンバリングは可能。
with test_Table as(
select code = 1301,Period = 200303 union all
select code = 1301,Period =200403 union all
select code = 1301,Period =200503 union all
select code = 1301,Period =200603 union all
select code = 1301,Period =200703 union all
select code = 1301,Period =200803 union all
select code = 2121,Period =200609 union all
select code = 2121,Period =200709 union all
select code = 2121,Period =200809 union all
select code = 7203,Period =200303 union all
select code = 7203,Period =200403 union all
select code = 7203,Period =200503 union all
select code = 7203,Period =200603 union all
select code = 7203,Period =200703 union all
select code = 7203,Period =200803
)select *
, num1 = rank() over(partition by code order by period)
, num2 = rank() over(order by Code ,period)
from test_Table