none
SQL文のWhere句で文字を比較 RRS feed

  • 質問

  • SQL文の書き方について質問です。

    [取引年月度]はvarchar(6)で定義されている場合、

    SELECT SUM(取引金額) as 金額 FROM 仕入伝票明細 WHERE 取引年月度 <= '201910'

    を実行すると、数値で比較する場合と同じ結果で例えば、201909、201801など201910以下の数値の取引年月度のものがSELECTされます。

    これは正しい書き方でしょうか?

    取引年月度を数値(整数)に変換して比較する方法はありますでしょうか?

    どうぞ宜しくお願い致します。

    2019年10月10日 5:37

すべての返信

  • > 数値で比較する場合と同じ結果で例えば、201909、201801など201910以下の数値の取引年月度のものがSELECTされます。これは正しい書き方でしょうか?

    「201909、201801など201910以下の数値の取引年月度のものがSELECT」が目的であれば、「期待した結果が得られる」=「正しい」と言っていいと思います。

    照合順序と使用されている文字によって ORDER BY の結果が変わる(なので、WHERE xxx <= 'yyy' が期待と異なるかもしれない)のですが、数字だけなら期待した結果になると思います。


    > 取引年月度を数値(整数)に変換して比較する方法はありますでしょうか?

    t-sql varchar to int などをキーワードにググってみてください。以下のような記事がヒットすると思います。

    How to convert Varchar to INT
    https://www.tsql.info/sql/how-to-convert-varchar-to-int.php

    2019年10月10日 6:11
  • 並び順は照合順序で決まります。Windowsのロケール順かコード順になります。いずれにしても同じ種類の数字だけで構成された文字列の比較ですから、その比較で問題ないと思います。実際、そのように比較されたシステムは多数ありますし、それで問題が発生したということは知りません。ただ、注意しなければいけないのは桁数が違う場合です。この場合は比較に文字列長も加える必要がありますが、今回は6桁で統一されているため、その必要はありません。
    心配であれば、照合順序でコード順を指定しておけば安心でしょう。COLLATE JAPANESE_BIN
    ロケールによって数字の並びが変ることはないと思いますので、かなり必要ないとは思いますが、私も全てのロケールを知らないので言い切れません。もっとも、JAPANESE以外のロケールを使うことが無いのであれば、尚更です。

    数字に変換したいのであれば、castやconvert関数を使って下さい。ただそうであれば、6桁の文字列ではなく数字として格納するようにしても良かったかもしれません。と言っても、私の感覚では文字列として定義されていることが多いと思います。特に汎用機の時代は当たり前でしたので、その流れもあるのかもしれません。ちなみに私はDate型で定義して、日の部分は無視というか1を入れています。フォーマットで関数を使えるようになりますからね。ただ、欠点として無期限の表現ですが、999999とできないので299912のようになってしまいます。まぁ、ここは慣れかもしれません。あくまで一つのやり方で、これを勧めているわけではありません。


    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!


    • 編集済み trapemiya 2019年10月10日 6:18
    2019年10月10日 6:16
  • ご丁寧に判り易く解説して頂き、ありがとうございました。今後も宜しくお願い致します。
    2019年10月10日 8:33
  • ご丁寧に判り易く解説して頂き、ありがとうございました。今後も宜しくお願い致します。
    2019年10月10日 8:33
  • galapagoさん、こんにちは。フォーラムオペレーターのHarukaです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    SurferOnWwwさんとtrapemiyaさんから寄せられた投稿はお役に立ちましたか。
    参考になった投稿には [回答としてマーク] をお願い致します。

    また、下記のスクリプトをご参照いただければと思います。

    IF OBJECT_ID('purchase slip line') IS NOT NULL drop table  [purchase slip line]   
    go 
    create table [purchase slip line] 
    ([transaction amount]  int,
    [transaction date] date)
    insert into [purchase slip line] values 
    (1,'20150203'),(2,'20191126')
    
    SELECT SUM ([transaction amount]) as amount 
    FROM [purchase slip line] WHERE FORMAT([transaction date],'yyyyMM') <= '201910'
    /*
    amount
    -----------
    1
    */
    
    SELECT SUM ([transaction amount]) as amount 
    FROM [purchase slip line] WHERE cast(FORMAT([transaction date],'yyyyMM') as int) <= 201910
    /*
    amount
    -----------
    1
    */

    どうぞよろしくお願いします。


    MSDN/ TechNet Community Support Haruka

    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、
    ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~





    2019年10月17日 6:04
    モデレータ