当前位置: 首页 > 面试题库 >

Equals(=) vs. LIKE

尉迟禄
2023-03-14
问题内容

使用SQL时,=WHERE子句中使用而不是有什么好处LIKE

没有任何特殊的运营商,LIKE并且=是相同的,对不对?


问题答案:

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描述了如何=比较字符串:

确定两个字符串的比较如下:

a)如果X字符的长度不等于Y字符的长度,则出于比较目的,较短的字符串将有效地替换为已扩展为较长字符串的长度的自身副本通过在一个或多个填充字符的右侧进行串联,可以根据CS选择填充字符。如果CS具有NO
PAD属性,则填充字符是与实现相关的字符,不同于X和Y字符集中的任何字符,其比CS之下的任何字符串都少排序。否则,填充字符为。

b)X和Y的比较结果由整理序列CS给出。

c)根据排序顺序,两个字符串即使长度不同或包含不同的字符序列,也可能比较相等。当操作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划分为子字符串的情况,则为true:

i)M的子字符串是M的0个或多个连续的<字符表示>的序列,M的每个<字符表示>恰好是一个子字符串的一部分。

ii)如果P的第i个子字符串说明符是任意字符说明符,则M的第i个子字符串说明符是任何单个<字符表示>。

iii)如果P的第i个子串说明符是任意字符串说明符,则M的第i个子串说明符是0或更多<字符表示>的任何序列。

iv)如果P的第i个子字符串说明符既不是任意字符说明符也不是任意的字符串说明符,则根据 的整理顺序,M的第i个子字符串等于该子字符串说明符,而没有将 字符附加到M,并具有与该子字符串说明符相同的长度。

v)M的子串数量等于P的子串说明符数量。

(已添加重点。)

这很罗word,所以让我们分解一下。项ii和iii分别指通配符_%。如果P不包含任何通配符,则仅适用项目iv。OP对此很感兴趣。

在这种情况下,它将使用当前的排序规则将每个“子字符串”(单个字符)M与每个子字符串P进行比较。

结论

最重要的是,在比较字符串时,=比较整个字符串,而一次只LIKE比较一个字符。两种比较都使用当前的排序规则。如本文中的第一个示例所示,这种差异在某些情况下会导致不同的结果。

您应该使用哪一个?没有人能告诉您-您需要使用适合您的用例的一种。不要通过切换比较运算符来过早地进行优化。



 类似资料:
  • 比较两个相等的日期。 当且仅当参数不为null并且是一个Date对象时,结果才为真,该对象表示与此对象相同的时间点,以毫秒为单位。 因此,当且仅当getTime方法为两者返回相同的long值时,两个Date对象才相等。 语法 (Syntax) public boolean equals(Object obj) 参数 (Parameters) obj - 要与之比较的对象。 返回值 (Return

  • 该方法确定调用方法的Number对象是否等于作为参数传递的对象。 语法 (Syntax) public boolean equals(Object o) 参数 (Parameters) o - 任何对象。 返回值 (Return Value) 如果参数不为null并且是相同类型且具有相同数值的对象,则方法返回True。 例子 (Example) 以下是此方法的使用示例 - class Examp

  • 描述 (Description) 该方法确定调用方法的Number对象是否等于作为参数传递的对象。 语法 (Syntax) public boolean equals(Object o) 参数 (Parameters) 这是参数的细节 - Any object. 返回值 (Return Value) 如果参数不为null并且是相同类型且具有相同数值的对象,则该方法返回True。 Java API

  • Compare this to another sequence for equality. Signature Sequence.equals = function(other, equalityFn) { /*...*/ } Sequence.equals = function equals(other, equalityFn) { if (!(other instanceof Seque

  • 问题内容: 如果我为一个类实现,是否仍然需要重写该方法?还是会为之工作? 如果答案为 否 ,那么如果出现差异怎么办?比方说,我的方式长期两个对象作为内享有平等的方法是从我的方式长期在同一类的两个对象为内平等不同的。 而且,如果我实施了,是否还必须重写? 问题答案: 虽然建议(并且非常明智)暗示它(反之亦然),但这 不是 必需的。旨在在对一系列对象执行排序时使用,而仅测试直接相等性。 该链接提供了一

  • 问题内容: 输出是 只是对.equals有一个简单的问题。 不管对象内容如何,仅当两个对象引用都指向同一对象时才返回true吗? 编辑 :现在我了解有关的部分,但是为什么2号线和3号线也不会返回? 编辑 :我相信看参考变量的地址,因此s1和s2不能相等。如果我的假设不正确,请纠正我 问题答案: 是,,这意味着两个对象引用不同,结果为false。 对于,您可以使用 为了进行编辑,您要在两个不同的St