none
SQL Serverにおける文字列の比較 RRS feed

  • 質問

  • こんにちは。

    いつも参考にさせていただいております。

    SQL Server 2005にて、yyyy/mm/dd という形のデータが入るchar(10)の列があるテーブルを操作しています。

    今まで特に気にせず、文字列のままWHERE文で比較していたのですが(うまくいっているように見えたので)、

    最近なぜうまくいくのか気になり調べてみました。

    株式会社トップスタジオのSQL Server 2005ビギナーズガイドには、同じ文字位置で比較する(1番目の文字どうし、2番目の文字どうし…というように)と書いてあり、比較する文字の長さが違う時は短い方の最後の空白を入れて長さをそろえると書いてありました。(照合順序で大小をつけるとも書いてあったと思います。)

    しかし、これだけだと1番目の文字から比較するのか、また、違う文字が初めて来た時点の、その文字どうしの大小で比較が終わるのかが書いてありませんでした。

    Oracleの方はそういった記述があり、SQL Server2005にて実際に試してみてもそのとおり動いているように見えるのですが、イマイチ自分の確かめ方で合っているかわかりません。

    そこで、①SQL Serverの文字列比較の部分の動作について教えてください。

    もしくは、(書籍等には書いてないかもしれないので)②上記のようにビギナーズガイドに書いてあった部分は正しいものとして、最初の文字から比較し区別がつく初めての文字で大小を決めるといった部分を確かめるには、何をもってそう判断したらよいでしょうか、ご教授願えませんでしょうか。(この動作で正しいと思って書いてますが、違ったらご指摘願います。)

    最後に③ふつうは文字列比較を使わないのでしょうか。特に日付に関して。

    以上、よろしくお願いいたします。

    2010年4月1日 13:19

回答

  • こんにちは、nagino です。

    # 投稿直前にうっかり消してしまって書き直したので、ちょっと凹み中です。
    # 書き直したものの分量が半減したので、何か記載漏れがあるかも・・・?

    SQL Server では、比較演算子など SQL の基本的な事項は ANSI の標準規格に準拠しています。
    単純に比較演算子の挙動について知りたいのであれば、ANSI の規格書をあたるのが確実ですが、なかなかな値段になります。
    文字列同士の比較演算では、基本的には辞書式順序で比較します。
    ただし、照合順序が関係してくるといくつか考慮すべきポイントが生じます。

     

    ここまでの流れを追うと照合順序の話が出ていますので、照合順序と文字列の比較との関連を知りたいということのようですね。
    公開されていない詳細な仕様については、Microsoft の有償サポートに問い合わせされるのが一番確実ですが、参考までに私が把握している範囲でいくつか補足しておきます。

     

    先ず、ここでは Windows 照合順序に限定して考えます。
    SQL 照合順序は互換性のために維持されており現在は Windows 照合順序を利用することが推奨されているということと、実装の過程で特殊な実装がされたものが見受けられることから、ここでは触れません。

    ちなみに余談ですが、Windows 照合順序は基本的に Windows OS が管理しています。
    SQL Server はその管理されている照合順序を利用している形です。
    ですので、.NET Framework でアプリケーションを作った場合も、SQL Server と同様の並び替え順序を実現することができます。
    (そのため、SQL Server に関するドキュメントより、Windows OS における Unicode のサポートや、Windows 上の開発での文字列処理に関するドキュメントなどの方が詳細が記載されているかもしれません。)
    辞書式順序が広く一般に使われている中で、Windows OS や ANSI の SQL がそれに従ったという流れではないかと思います。

    また、スペイン語の Ch から始まる単語の扱いなど、言語ごとに特殊な要因がありますので、日本語についてのみ考えます。
    日本語も特殊な要因がありますが、そのうちのいくつか理解しておくべき事項については最後に触れます。

     

    さて、照合順序と文字列の比較との関連を理解するためには 2 点基礎的な内容を理解しておく必要があります。

    1 つめは文字コード(コードポイント)です。
    Windows OS では、いくつかの理由から Shift JIS と Unicode がサポートされています。
    SQL Server でも同様です。
    現在はいずれも JIS やユニコードコンソーシアムといったところが標準を定義しており、Microsoft が定義しているわけではありません。
    ただし、実装の過程で歴史上の問題などから、一部標準と差異(Shift JIS は全角チルダ、Unicode はサロゲートペアや結合文字)がありますので注意が必要です。
    個々の差異については検索すれば情報が出てきますし、ここでは全体像や基本事項をテーマとして考えていますので、詳細は割愛します。

    2 つめはバイナリ照合順序です。
    これは、文字列を比較する際に辞書式順序を使い、各文字の比較は文字コード別に行います。
    細かい話をすると、文字列の長さが異なる場合は短いほうに半角スペースを追加して長さを揃えてから比較します。
    このあたりの半角スペースによる長さ揃えなども ANSI の SQL-92 で定義された動作で、Microsoft が定義しているわけではありません。
    http://support.microsoft.com/default.aspx?scid=kb;EN-US;316626
    (日本語版の KB は機械翻訳ですが、仕様について記載した厳密性を要求されるドキュメントのため、とても読めるレベルにありません。また、KB 自体は LIKE 演算子だけ ANSI SQL-92 と異なる挙動をすることに関する内容です。)

    ここまでの 2 点を確認するためのクエリを 1 つ例示しておきます。
    全角の「A」とカタカナの「ア」を比較しています。
    バイナリ照合順序で文字コードによって文字の大小関係が変化していることが確認できます。

    DECLARE @ShiftJis1 char(2)
    DECLARE @ShiftJis2 char(2)
    DECLARE @Unicode1 nchar(1)
    DECLARE @Unicode2 nchar(1)

    SET @ShiftJis1 = 'A'
    SET @ShiftJis2 = 'ア'
    SET @Unicode1 = N'A'
    SET @Unicode2 = N'ア'

    SELECT
     CASE
      WHEN @ShiftJis1 < @ShiftJis2 COLLATE Japanese_90_BIN2 THEN 'ShiftJis <'
      ELSE 'ShiftJis >'
     END

    SELECT
     CASE
      WHEN @Unicode1 < @Unicode2 COLLATE Japanese_90_BIN2 THEN 'Unicode <'
      ELSE 'Unicode >'
     END

     

    ここまでを前提として、日本語のバイナリ照合順序以外の照合順序を考えます。
    これらは日本語特有の要因が関連しています。
    日本語では半角の「0」と全角の「0」、ひらがなの「あ」とカタカナの「ア」など、同じ意味を持つ文字が多数あります。
    これらを同じとみなすかどうかについて、照合順序のサフィックスでその動作を定義することができます。
    http://technet.microsoft.com/ja-jp/library/ms143515.aspx

    ただし、バイナリ照合順序以外の場合は、この同じ意味かどうかを判断するための情報を持つ必要があります。
    そのため、文字コードではなくそれらを勘案した重みを別途管理して、それに基づき比較を行っています。
    この重みを管理しているデータを過去の経緯から私は重み付けテーブルと呼んでいるので、ここではこの(非公式な)用語で以下記載します。
    実際の実装はさておき、バイナリ照合順序は文字コードで、バイナリ以外の照合順序は重み付けテーブルで比較すると理解されると良いと思います。
    (実際の実装は非公開ですので、厳密には重み付けテーブルが存在するかどうか自体も謎です。ただし動作を理解しやすいので、以下では存在を前提に記載します。)

    重み付けテーブルには各文字の重みを設定します。
    基本的には文字コードに対応する重みを設定し、同じ意味と判断する文字だけ文字コードと異なる重み(同じ意味の文字には同じ重み)を設定します。
    重み付けテーブルを作成した時点で文字が割り当てられていない文字コードについては当然設定しません。
    しかし Unicode が 既に 5.0 まで拡張されたように、後から追加された文字が多数あります。
    これらは重み付けテーブルでは重みが無いため、並び替えなどでは空文字と同様に処理されます。
    重み付けテーブルはバージョンごとに更新されていて、それらが照合順序の Japanese、Japanese_90、Japanese_100 といった数字(世代)に該当します。
    また、同じ文字とする文字についてはどちら側の文字として処理されるか(半角の「0」を全角の「0」と読み替えるのか、全角の「0」を半角の「0」と読み替えるのか)については明記したドキュメントは無かったかと思います。
    そのため、実態としては Microsoft 独自仕様と言えなくもありません。

    バイナリ照合順序は文字コードによる単純比較なので、重み付けが無い今後追加される文字もソートできる、パフォーマンスが良い、仕様が明確です。
    ですので、仕様を明らかにする必要があるケースではバイナリ照合順序を使用するのがお勧めです。
    他システムとの互換性や、一般的なアプリケーションの動作でよいという場合は適切な照合順序を選択すれば良いかと思います。
    ただしその場合も、重み付けテーブルの内容を考えて可能な限り新しい世代の照合順序を使うことがお勧めです。

     

    システムにおける照合順序は基本的にはアーキテクトが判断、決定する事項だと思いますので、通常開発者や管理者はここまで深い理解は必要なく Technet/MSDN ライブラリで公開されている程度の情報で十分だと思います。
    ただ、いくつか関連情報も公式にリリースされていますので、参考までにあげておきます。
    ただ、なにはともあれ ANSI の規格書が一番の基本です。

    ●SQL Server の JIS2004 対応に関するガイドライン
    http://www.microsoft.com/downloads/details.aspx?FamilyId=E942342A-719F-4841-A9D2-F6D9FD58299F&displaylang=ja
    ●マイクロソフト公式解説書 Unicode による JIS X 0213 実装入門
    ISBN 978-4-89100-608-2
    (※手元の初版は誤字、誤植が非常に多く、とても読めません。そろそろ新しい版をもう 1 冊買おうと思いつつ忘れていました・・・。)

     

    他に余談として、他の言語の BIN2 と Japanese_90_BIN2 との違いは何か?(実際挙動に差異は無いが、異なる照合順序同士は比較演算できないので COLLATE 句の指定が必要)ですとか、SQL Server 2008 / Windows Server 2008 から実装された部首画数順(文字コード順ではない)ですとか、色々掘り下げると技術的に面白い事項ではあります。
    私も ANSI の SQL-92 を全て把握しているわけではないので、ANSI で照合順序がどういう位置づけなのかといったことはちょっと分かりません。
    10 数部からなる規格書が JSA で販売されていますが、1 部数万円するので個人ではちょっと手が出ません。(いずれは欲しいですが・・・)

    誤記や不足にお気づきの方は、補足いただければ幸いです。

     


    MCITP(Database Developer/Database Administrator)
    2010年4月3日 10:52

すべての返信

  • > これだけだと1番目の文字から比較するのか、
    > また、違う文字が初めて来た時点の、その文字どうしの大小で比較が終わるのか

    数値にしても文字列にしても、「比較の単位で確認して、最初に差異が発生した以降」によって順序が変化することはありませんよね。このため、差異が発生した以降を比較しているとは考えにくいです。

    ただ、それがどこかに明示されているかどうかによって、SQL Server に文字列を与える側に変化が生じるわけではないですよね。ですので、比較方法は不具合なくパフォーマンスのよいように日々改良されてくれればいいんじゃないでしょうか。比較結果や比較ロジックに影響しないような仕様を明文化してしまうことは、そういった改良を阻んでしまったり、利用者に無意味な思慮を発生させるだけではないかと思います。

    必要なことは、2つの文字列の大小がどのようなルールで比較するかが明確に定義されていることと、そのルール通りに大小が判定されることであって、比較処理がどのように行われているかはわざわざ記載する必要がない(むしろ、書いてないほうがよい)ことでしょう。

    > ふつうは文字列比較を使わないのでしょうか。特に日付に関して。

    日付は日付で保持、比較するのが一般的だと思います。日付として保持し、日付として比較するならば日付としての順序値で並べ替えられます。たとえば、「2009/03/04」と「平成22年4月1日」と「01-Apr-2009」を比較しても、それが日付であれば正しく並べることができますが、文字列のままでは正常に並べ替えることができません。

    データの持ち方が日付であるということは、日付を表現する方法を自由に選んで入出力できる、ということです。もちろん、日付で保持する以上は日付としての制約も発生することになり、それがシステムとして許容できない場合もあります。

    ※ 日付型の制約としては、どのような型を利用するかによりますが、西暦1年より過去が扱えないとか、「5月40日」のような日付として不正な状態を保持できない等があげられます。

    2010年4月1日 15:26
  • > これだけだと1番目の文字から比較するのか、
    > また、違う文字が初めて来た時点の、その文字どうしの大小で比較が終わるのか

    数値にしても文字列にしても、「比較の単位で確認して、最初に差異が発生した以降」によって順序が変化することはありませんよね。このため、差異が発生した以降を比較しているとは考えにくいです。

    ただ、それがどこかに明示されているかどうかによって、SQL Server に文字列を与える側に変化が生じるわけではないですよね。ですので、比較方法は不具合なくパフォーマンスのよいように日々改良されてくれればいいんじゃないでしょうか。比較結果や比較ロジックに影響しないような仕様を明文化してしまうことは、そういった改良を阻んでしまったり、利用者に無意味な思慮を発生させるだけではないかと思います。

    必要なことは、2つの文字列の大小がどのようなルールで比較するかが明確に定義されていることと、そのルール通りに大小が判定されることであって、比較処理がどのように行われているかはわざわざ記載する必要がない(むしろ、書いてないほうがよい)ことでしょう。

    > ふつうは文字列比較を使わないのでしょうか。特に日付に関して。

    日付は日付で保持、比較するのが一般的だと思います。日付として保持し、日付として比較するならば日付としての順序値で並べ替えられます。たとえば、「2009/03/04」と「平成22年4月1日」と「01-Apr-2009」を比較しても、それが日付であれば正しく並べることができますが、文字列のままでは正常に並べ替えることができません。

    データの持ち方が日付であるということは、日付を表現する方法を自由に選んで入出力できる、ということです。もちろん、日付で保持する以上は日付としての制約も発生することになり、それがシステムとして許容できない場合もあります。

    ※ 日付型の制約としては、どのような型を利用するかによりますが、西暦1年より過去が扱えないとか、「5月40日」のような日付として不正な状態を保持できない等があげられます。

    2010年4月1日 15:26
  • K.Takaoka様

    回答ありがとうございます。

    > 数値にしても文字列にしても、「比較の単位で確認して、最初に差異が発生した以降」によって順序が変化することはありませんよね。このため、差異が発生した以降を比較しているとは考えにくいです。

    おっしゃるとおり、考えてみるとその通りですね。細かいところまでは明文化されていない方がよいのかもしれません。

    > 必要なことは、2つの文字列の大小がどのようなルールで比較するかが明確に定義されていることと

    とありますが、私が調べた限りだと照合順序はいろいろあるようですが、それがどういうルールかという記述をみつけることができなかったため、やはり判断がつきません。あまり詳しく読んでいませんが、照合順序は1文字ずつのソート順(大小)だけの定義のように思います。やはり、最初の文字から1文字ずつ比較するという程度の記述は、それほど詳細な定義でもないですし、明記されてくれていた方がありがたいと思いました。(一般常識的に考えれば、辞書でならぶ順番のとおりで大小が決まるのでしょう。)

    この話の流れからいって、1文字ずつのソート順は照合順序により決まり、それを踏まえ文字列として評価する場合は辞書でならぶ順番(1文字目から評価)と考えてよいのでしょうか。

    > 日付は日付で保持、比較するのが一般的だと思います。

    わかりました。とりあえず今回はchar型で話が進んでいるため、次回からの参考にしたいと思います。文字列で比較しなければいけないことも今後出てくるかもしれませんので。

    2010年4月1日 15:57
  • > それがどういうルールかという記述をみつけることができなかった

    http://msdn.microsoft.com/ja-jp/library/ms188046(v=SQL.100).aspx
    http://msdn.microsoft.com/ja-jp/library/ms180175.aspx

    「比較の単位で」と書いているのは、それが照合順序によっては char(1) や nchar(1) とは限らないためです。比較時に無視される文字や同一視される文字なんかの定義もあります。"A" と "A" をどう扱うかとか、特に日本語圏では混在されていることが多くて影響が大きいですね。

     

    2010年4月2日 9:37
  • 回答ありがとうございます。

    リンク先を見たら、Transact-SQLの構文がわかりませんでした…orz

    でもよく見てみると、情報処理試験かなんかで見たことある構文だと思ってちょっと調べたら理解できました!なんか思わぬ副産物を得てラッキーでした。

    と、余談はこのくらいにして話を進めたいと思います。

     

    はじめに謝っておきますが、とても長くなってしまいました。。ごめんなさい。

     

    > 比較の単位で」と書いているのは、それが照合順序によっては char(1) や nchar(1) とは限らないためで

    これは、SQL Server 2008オンラインブックの「照合順序の使用」にあった、”しかし、メキシコ在住のスペイン語を話す人であれば、'Ch' で始まる単語が 'C' で始まる単語の末尾に並べ替えられることを予測するかもしれません”的な場合だと理解しました。

    リンク先については一度目を通していたのですがTransact-SQLもわかったことですし(笑)再度目を通してみました。

    とりあえずWindows照合順序の方で話しますが、"CollationDesignator"のところに”・辞書順での並べ替えを指定した場合に適用される並べ替え規則。並べ替え規則は、アルファベットまたは言語に基づきます。”と書いてありました。これを辞書式順序(http://ja.wikipedia.org/wiki/%E8%BE%9E%E6%9B%B8%E5%BC%8F%E9%A0%86%E5%BA%8F)まで適用されたものと拡大解釈すれば、たしかに"Japanese_??_??"とか指定すれば、日本語の辞書順(ってことですよね)なんだなと思います。

    しかし、この日本語の辞書順ってのが、なんかの規格で決まっているわけではなく、Microsoftの人が決めた基準なのではないでしょうか。わたしが「それがどういうルールかという記述をみつけることができなかったため」と書いた部分に関して言えば、Collate句の指定の仕方がわからないのではなく、このMicrosoftが決めた日本語辞書順のルールはどこに書いてあるんだろうかということです。

    さらに、同リンク先の「Latin1_General_BIN」の説明に会ったように"照合順序に、コード ページ 1252 とバイナリ並べ替え規則が使用されます。Latin1 一般辞書の並べ替え規則は無視されます。"というところをみると、先ほどの辞書式順序の拡大解釈も無理があると思います。バイナリ並べ替え規則も読みましたが、1文字ごとの説明しか無かったように思います。

    中学のとき国語が50点くらいだったため、あまり日本語の解釈には自信がありませんので(笑)、こう捉えればいいんだよというのがあればご教授ください。

    やっぱりそこは一般常識でわかるでしょ?ってことなんでしょうか。

    とりあえず明日、もう一度トップスタジオの本を読んでみます。今手元に無いので。

    2010年4月2日 13:12
  • こんにちは、nagino です。

    # 投稿直前にうっかり消してしまって書き直したので、ちょっと凹み中です。
    # 書き直したものの分量が半減したので、何か記載漏れがあるかも・・・?

    SQL Server では、比較演算子など SQL の基本的な事項は ANSI の標準規格に準拠しています。
    単純に比較演算子の挙動について知りたいのであれば、ANSI の規格書をあたるのが確実ですが、なかなかな値段になります。
    文字列同士の比較演算では、基本的には辞書式順序で比較します。
    ただし、照合順序が関係してくるといくつか考慮すべきポイントが生じます。

     

    ここまでの流れを追うと照合順序の話が出ていますので、照合順序と文字列の比較との関連を知りたいということのようですね。
    公開されていない詳細な仕様については、Microsoft の有償サポートに問い合わせされるのが一番確実ですが、参考までに私が把握している範囲でいくつか補足しておきます。

     

    先ず、ここでは Windows 照合順序に限定して考えます。
    SQL 照合順序は互換性のために維持されており現在は Windows 照合順序を利用することが推奨されているということと、実装の過程で特殊な実装がされたものが見受けられることから、ここでは触れません。

    ちなみに余談ですが、Windows 照合順序は基本的に Windows OS が管理しています。
    SQL Server はその管理されている照合順序を利用している形です。
    ですので、.NET Framework でアプリケーションを作った場合も、SQL Server と同様の並び替え順序を実現することができます。
    (そのため、SQL Server に関するドキュメントより、Windows OS における Unicode のサポートや、Windows 上の開発での文字列処理に関するドキュメントなどの方が詳細が記載されているかもしれません。)
    辞書式順序が広く一般に使われている中で、Windows OS や ANSI の SQL がそれに従ったという流れではないかと思います。

    また、スペイン語の Ch から始まる単語の扱いなど、言語ごとに特殊な要因がありますので、日本語についてのみ考えます。
    日本語も特殊な要因がありますが、そのうちのいくつか理解しておくべき事項については最後に触れます。

     

    さて、照合順序と文字列の比較との関連を理解するためには 2 点基礎的な内容を理解しておく必要があります。

    1 つめは文字コード(コードポイント)です。
    Windows OS では、いくつかの理由から Shift JIS と Unicode がサポートされています。
    SQL Server でも同様です。
    現在はいずれも JIS やユニコードコンソーシアムといったところが標準を定義しており、Microsoft が定義しているわけではありません。
    ただし、実装の過程で歴史上の問題などから、一部標準と差異(Shift JIS は全角チルダ、Unicode はサロゲートペアや結合文字)がありますので注意が必要です。
    個々の差異については検索すれば情報が出てきますし、ここでは全体像や基本事項をテーマとして考えていますので、詳細は割愛します。

    2 つめはバイナリ照合順序です。
    これは、文字列を比較する際に辞書式順序を使い、各文字の比較は文字コード別に行います。
    細かい話をすると、文字列の長さが異なる場合は短いほうに半角スペースを追加して長さを揃えてから比較します。
    このあたりの半角スペースによる長さ揃えなども ANSI の SQL-92 で定義された動作で、Microsoft が定義しているわけではありません。
    http://support.microsoft.com/default.aspx?scid=kb;EN-US;316626
    (日本語版の KB は機械翻訳ですが、仕様について記載した厳密性を要求されるドキュメントのため、とても読めるレベルにありません。また、KB 自体は LIKE 演算子だけ ANSI SQL-92 と異なる挙動をすることに関する内容です。)

    ここまでの 2 点を確認するためのクエリを 1 つ例示しておきます。
    全角の「A」とカタカナの「ア」を比較しています。
    バイナリ照合順序で文字コードによって文字の大小関係が変化していることが確認できます。

    DECLARE @ShiftJis1 char(2)
    DECLARE @ShiftJis2 char(2)
    DECLARE @Unicode1 nchar(1)
    DECLARE @Unicode2 nchar(1)

    SET @ShiftJis1 = 'A'
    SET @ShiftJis2 = 'ア'
    SET @Unicode1 = N'A'
    SET @Unicode2 = N'ア'

    SELECT
     CASE
      WHEN @ShiftJis1 < @ShiftJis2 COLLATE Japanese_90_BIN2 THEN 'ShiftJis <'
      ELSE 'ShiftJis >'
     END

    SELECT
     CASE
      WHEN @Unicode1 < @Unicode2 COLLATE Japanese_90_BIN2 THEN 'Unicode <'
      ELSE 'Unicode >'
     END

     

    ここまでを前提として、日本語のバイナリ照合順序以外の照合順序を考えます。
    これらは日本語特有の要因が関連しています。
    日本語では半角の「0」と全角の「0」、ひらがなの「あ」とカタカナの「ア」など、同じ意味を持つ文字が多数あります。
    これらを同じとみなすかどうかについて、照合順序のサフィックスでその動作を定義することができます。
    http://technet.microsoft.com/ja-jp/library/ms143515.aspx

    ただし、バイナリ照合順序以外の場合は、この同じ意味かどうかを判断するための情報を持つ必要があります。
    そのため、文字コードではなくそれらを勘案した重みを別途管理して、それに基づき比較を行っています。
    この重みを管理しているデータを過去の経緯から私は重み付けテーブルと呼んでいるので、ここではこの(非公式な)用語で以下記載します。
    実際の実装はさておき、バイナリ照合順序は文字コードで、バイナリ以外の照合順序は重み付けテーブルで比較すると理解されると良いと思います。
    (実際の実装は非公開ですので、厳密には重み付けテーブルが存在するかどうか自体も謎です。ただし動作を理解しやすいので、以下では存在を前提に記載します。)

    重み付けテーブルには各文字の重みを設定します。
    基本的には文字コードに対応する重みを設定し、同じ意味と判断する文字だけ文字コードと異なる重み(同じ意味の文字には同じ重み)を設定します。
    重み付けテーブルを作成した時点で文字が割り当てられていない文字コードについては当然設定しません。
    しかし Unicode が 既に 5.0 まで拡張されたように、後から追加された文字が多数あります。
    これらは重み付けテーブルでは重みが無いため、並び替えなどでは空文字と同様に処理されます。
    重み付けテーブルはバージョンごとに更新されていて、それらが照合順序の Japanese、Japanese_90、Japanese_100 といった数字(世代)に該当します。
    また、同じ文字とする文字についてはどちら側の文字として処理されるか(半角の「0」を全角の「0」と読み替えるのか、全角の「0」を半角の「0」と読み替えるのか)については明記したドキュメントは無かったかと思います。
    そのため、実態としては Microsoft 独自仕様と言えなくもありません。

    バイナリ照合順序は文字コードによる単純比較なので、重み付けが無い今後追加される文字もソートできる、パフォーマンスが良い、仕様が明確です。
    ですので、仕様を明らかにする必要があるケースではバイナリ照合順序を使用するのがお勧めです。
    他システムとの互換性や、一般的なアプリケーションの動作でよいという場合は適切な照合順序を選択すれば良いかと思います。
    ただしその場合も、重み付けテーブルの内容を考えて可能な限り新しい世代の照合順序を使うことがお勧めです。

     

    システムにおける照合順序は基本的にはアーキテクトが判断、決定する事項だと思いますので、通常開発者や管理者はここまで深い理解は必要なく Technet/MSDN ライブラリで公開されている程度の情報で十分だと思います。
    ただ、いくつか関連情報も公式にリリースされていますので、参考までにあげておきます。
    ただ、なにはともあれ ANSI の規格書が一番の基本です。

    ●SQL Server の JIS2004 対応に関するガイドライン
    http://www.microsoft.com/downloads/details.aspx?FamilyId=E942342A-719F-4841-A9D2-F6D9FD58299F&displaylang=ja
    ●マイクロソフト公式解説書 Unicode による JIS X 0213 実装入門
    ISBN 978-4-89100-608-2
    (※手元の初版は誤字、誤植が非常に多く、とても読めません。そろそろ新しい版をもう 1 冊買おうと思いつつ忘れていました・・・。)

     

    他に余談として、他の言語の BIN2 と Japanese_90_BIN2 との違いは何か?(実際挙動に差異は無いが、異なる照合順序同士は比較演算できないので COLLATE 句の指定が必要)ですとか、SQL Server 2008 / Windows Server 2008 から実装された部首画数順(文字コード順ではない)ですとか、色々掘り下げると技術的に面白い事項ではあります。
    私も ANSI の SQL-92 を全て把握しているわけではないので、ANSI で照合順序がどういう位置づけなのかといったことはちょっと分かりません。
    10 数部からなる規格書が JSA で販売されていますが、1 部数万円するので個人ではちょっと手が出ません。(いずれは欲しいですが・・・)

    誤記や不足にお気づきの方は、補足いただければ幸いです。

     


    MCITP(Database Developer/Database Administrator)
    2010年4月3日 10:52
  • nagino 様

    回答ありがとうございます。とても詳しくてなんというか、脱帽致しました。

    私もいろいろ調べたので半分くらいは理解しているつもりでしたが、いろいろ知らない情報があり大変助かりました。

    一番知りたかったのは冒頭の

    >SQL Server では、比較演算子など SQL の基本的な事項は ANSI の標準規格に準拠しています。
    >単純に比較演算子の挙動について知りたいのであれば、ANSI の規格書をあたるのが確実ですが、なかなかな値段になります。
    >文字列同士の比較演算では、基本的には辞書式順序で比較します。

    というところでした。

    私も本で調べてみまして、トップスタジオの別の本にSQL Server2005はSQL-92に準拠していると書いてありました。
    (ただその準拠というのが100%同じなのかどうか…)

    ですが基本的に辞書式順序で比較しますというお答えを頂きましたので、それでよしとしたいと思います。

    また、今回回答をいただきましたが、自分で考えたところでは、他のデータベースと違う仕様だった場合、もっとネット上で大問題になっているのではないかということを考え、照合順序という独自仕様はありますが辞書式順序とか基本的な部分は他と変わらないんだろうなと考えました。

    ここを読まれた方でさらに補足やズバリの出典が提示できる方がいればお願いしたいのですが、とりあえず回答をつけたいと思います。

    大変ありがとうございました!

    (私は結構細かい質問するのであんまり回答つかないんですよね…(^^ゞ)

    2010年4月5日 13:05
  • > 他のデータベースと違う仕様だった場合、もっとネット上で大問題になっているのでは
    > ないかということを考え、照合順序という独自仕様はありますが辞書式順序とか基本的な
    > 部分は他と変わらないんだろうなと考えました。

    このあたりは、実業務では

     * データベースの返す順で納得してもらう

    または

     * アプリケーションで順序を明確に定義する

    ということがほとんどなので、問題になることがないのかもしれません。順序を厳密に考慮しない場合は前者、厳密に考慮する場合は後者で開発されるため、データベースによる並べ替え順序の差異がどのようになろうとも問題として表面化しないほど微細であるか、表面化されないように設計されているということですね。

    特に、データ全体を文字列で並べ替えることは少なく、通常は数値や日付のような(おおむね)普遍的な順序値を持つ項目があり、文字列の部分に依存した並べ替え順序は軽視される傾向があると思います。
    # 名簿を誕生日順に並べたときの順序は厳密だが、名前順に並べたときの差異は「いつも同じならよい」ってことですね

    2010年4月12日 3:26