(SQL)時間、分を別列に分けた仕様の時に、時間文字列を生成する方法
時間という情報を格納するのに datetime 型の時間の部分だけに入れることが多いかもしれませんが、24時を超えた時間を「25」という値で持ちたい時があるかもしれません。(まあ、datetime で日付を+1して保存するという方法もあるかもしれませんが。。)
というわけで、 "Hour"列と"Minute"列をint型で用意して、それに時間を保存するパターンについてのノウハウです。
DMBMSはSQL Server2005です。
この状態でSQLで時間を条件にしたい時、"Hour"列と"Minute"列を文字列(varchar)に直して比較したいわけですが、この文字列に直すというのが結構曲者でした。
普通に
SELECT STR( Hour , 2 ) + ':' + STR( Minute , 2) + ':00'
とすると、一桁の数値の場合
9:1:00
という風になってしまいます。
ということで、"Hour"列と"Minute"列の値が一桁の場合に0埋めするようにしました。
参考にさせてもらったのはこちらです。
0埋めする方法として下記のように記されていました。
--0埋めを行う(例、10桁)
SELECT RIGHT(REPLICATE('0', 10) + REPLACE(STR(@Number), ' ', ''), 10)
--結果: '0000000123'
なにやら関数だらけですが、ようは下記のような流れになっています。
まず REPLICATE('0', 10)。結果は "0000000000" になります。
これに STR(@Number) で数値を文字列化。このとき、STRの第2引数に値を入れないと自動的に空白の入った10桁の文字列ができます。@Numberが"3"だとすると結果は" 123"となります。
この空白の入った文字列から空白除去するために REPLACE 関数で空白を空文字に置換します。この結果は"123"となります。
"+"記号はSQL Serverでは文字列連結演算子なので、ここまでの結果は "0000000000123"となります。
最後に仕上げで RIGHT 関数で右から10桁切り取ります。
これでめでたく"0000000123"という結果が返るわけです。
さて、このコードを見た同僚はもっとシンプルにできるということで、下記のようなSQLを書いてくれました。
SELECT RIGHT('0000000000' + LTRIM(STR(@Number)), 10)
ようは空白除去に LTRIM 関数を、そして0埋めよう文字列は最初から''で用意しておくというわけです。
この方法で、Hour"列と"Minute"列を0埋めあり文字列に直すSQLはこうなりました。
SELECT RIGHT('00' + LTRIM(STR( Hour )), 2) + ':' + RIGHT('00' + LTRIM(STR( Minute )), 2) + ':00'
あとはこの形式(hh:mm:ss)に直した比較用変数で普通に比較できます。
例:
declare @Time DateTime SET @Time='13:00:00' SELECT * FROM TABLE WHERE RIGHT('00' + LTRIM(STR( Hour )), 2) + ':' + RIGHT('00' + LTRIM(STR( Minute )), 2) + ':00' > CONVERT(varchar, @Time, 108)
ちなみにこれはSQL Server専用です。
各DBMSでの文字列操作関数の違いはこちらに丁寧にまとめられています。
これを見ると文字列の連結(結合)もDBMSによって随分仕様が違うんですね。。