等しい(=) vs. いいね 質問する

等しい(=) vs. いいね 質問する

SQL を使用する場合、句で の代わり=にを使用することには何か利点がありますか?WHERELIKE

特別な演算子がなければ、LIKEと は=同じですよね?

ベストアンサー1

さまざまな演算子

LIKEと は=異なる演算子です。ここでの回答のほとんどはワイルドカードのサポートに焦点を当てていますが、これがこれらの演算子の唯一の違いではありません。

=は、数値と文字列に対して作用する比較演算子です。文字列を比較する場合、比較演算子は文字列全体を比較します。

LIKE文字ごとに比較する文字列演算子です。

問題を複雑にしているのは、両方のオペレーターが照合比較の結果に重要な影響を及ぼす可能性があります。

動機付けの例

まず、これらの演算子が明らかに異なる結果を生成する例を特定しましょう。MySQL マニュアルから引用します。

SQL 標準に従って、LIKE は文字ごとに一致を実行するため、= 比較演算子とは異なる結果が生成されることがあります。

mysql> SELECT 'ä' LIKE 'ae' COLLATE latin1_german2_ci;
+-----------------------------------------+
| 'ä' LIKE 'ae' COLLATE latin1_german2_ci |
+-----------------------------------------+
|                                       0 |
+-----------------------------------------+
mysql> SELECT 'ä' = 'ae' COLLATE latin1_german2_ci;
+--------------------------------------+
| 'ä' = 'ae' COLLATE latin1_german2_ci |
+--------------------------------------+
|                                    1 |
+--------------------------------------+

MySQL マニュアルのこのページは「文字列比較関数」と呼ばれ、=ここでは説明されていないことに注意してください。これは、=厳密には文字列比較関数ではないことを意味します。

どのように=機能しますか?

SQL標準§8.2文字列を比較する方法を説明します=

2 つの文字列の比較は次のように決定されます。

a) X の文字数の長さが Y の文字数の長さと等しくない場合、比較のために、短い方の文字列は、1 つ以上のパディング文字の右側に連結して長い方の文字列の長さまで拡張された自身のコピーに置き換えられます。パディング文字は CS に基づいて選択されます。CS に NO PAD 属性がある場合、パディング文字は、CS のどの文字列よりも小さい照合順序を持つ X および Y の文字セットのどの文字とも異なる実装依存の文字です。それ以外の場合、パディング文字は <スペース> です。

b) X と Y の比較の結果は照合シーケンス CS によって与えられます。

c) 照合順序によっては、長さが異なっていたり、文字のシーケンスが異なっていても、2 つの文字列が等しいと判断される場合があります。MAX、MIN、DISTINCT 操作、グループ化列への参照、および UNION、EXCEPT、INTERSECT 演算子が文字列を参照する場合、これらの操作によってこのような等しい値のセットから選択される特定の値は、実装に依存します。

(強調追加)

これは何を意味するのでしょうか?文字列を比較する場合、演算子は=現在の照合順序を薄くラップするだけです。照合順序とは、文字列を比較するためのさまざまなルールを持つライブラリです。以下は、MySQL からのバイナリ照合:

static int my_strnncoll_binary(const CHARSET_INFO *cs __attribute__((unused)),
                               const uchar *s, size_t slen,
                               const uchar *t, size_t tlen,
                               my_bool t_is_prefix)
{
  size_t len= MY_MIN(slen,tlen);
  int cmp= memcmp(s,t,len);
  return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
}

この特定の照合順序は、バイト単位で比較します (これが「バイナリ」と呼ばれる理由です。文字列に特別な意味を与えるものではありません)。他の照合順序では、より高度な比較が提供される場合があります。

例えば、ここにUTF-8 照合大文字と小文字を区別しない比較をサポートします。コードはここに貼り付けるには長すぎますが、リンクにアクセスして の本文を読んでくださいmy_strnncollsp_utf8mb4()。この照合は一度に複数のバイトを処理でき、さまざまな変換 (大文字と小文字を区別しない比較など) を適用できます。=演算子は、照合の予測不能性から完全に抽象化されています。

どのようにLIKE機能しますか?

SQL 標準 § 8.5文字列を比較する方法を説明しますLIKE

<述語>

M LIKE P

M を次のような部分文字列に分割できる場合、真となります。

i) M の部分文字列は、M の 0 個以上の連続した <文字表現> のシーケンスであり、M の各 <文字表現> は正確に 1 つの部分文字列の一部です。

ii) P の i 番目の部分文字列指定子が任意の文字指定子である場合、M の i 番目の部分文字列は任意の単一の <文字表現> です。

iii) P の i 番目の部分文字列指定子が任意の文字列指定子である場合、M の i 番目の部分文字列は 0 個以上の <文字表現> の任意のシーケンスになります。

iv) P の i 番目の部分文字列指定子が任意の文字指定子でも任意の文字列指定子でもない場合は、M の i 番目の部分文字列は、<like 述語> の照合順序に従ってその部分文字列指定子と等しく、M に <スペース> 文字が追加されず、その部分文字列指定子と同じ長さになります。

v) M の部分文字列の数は、P の部分文字列指定子の数に等しい。

(強調追加)

これはかなり長いので、分解してみましょう。項目 ii と iii は、それぞれワイルドカード_とを参照します。にワイルドカードが含まれていない場合は、項目 iv のみが適用されます。これは、OP が提起した興味深いケースです。%P

この場合、現在の照合を使用して、 の各「サブ文字列」(個々の文字)を のM各サブ文字列と比較します。P

結論

要するに、文字列を比較する場合、=は文字列全体を比較しますが、 はLIKE一度に 1 文字ずつ比較します。どちらの比較でも現在の照合順序が使用されます。この違いにより、この投稿の最初の例で明らかなように、場合によっては異なる結果が生じます。

どれを使用すべきでしょうか? 誰もそれを教えることはできません。ユースケースに適したものを使用する必要があります。比較演算子を切り替えて早まって最適化しないでください。

おすすめ記事