SQL:使用 <= 和 >= 比较字符串与通配符
SQL: Using <= and >= to compare string with wildcard
假设我 table 看起来像这样:
Id | Name | Age
=====================
1 | Jose | 19
2 | Yolly | 26
20 | Abby | 3
29 | Tara | 4
而我的查询语句是:
1) Select * from thisTable where Name <= '*Abby';
它 returns 0 行
2) Select * from thisTable where Name <= 'Abby';
returns 与艾比
排
3) Select * from thisTable where Name >= 'Abby';
returns 所有行 // 第 1-4 行
4) Select * from thisTable where Name >= '*Abby';
returns 所有行; // 第 1-4 行
5) Select * from thisTable where Name >= '*Abby' and Name <= "*Abby";
returns 0 行。
6) Select * from thisTable where Name >= 'Abby' and Name <= 'Abby';
returns 与 Abby 并列;
我的问题:为什么我会得到这些结果?通配符如何影响查询结果?如果条件是 Name <= '*Abby'
为什么我得不到任何结果?
因为,>=
和<=
是比较运算符。他们根据 ASCII 值比较字符串。
因为ASCII值*是42和ASCII大写字母的值从65,这就是为什么当您尝试 name<='*Abby'
、sql-server 时选择字符串中第一个字符的 ASCII 值(即 42),因为数据中没有任何值的第一个字符 ASCII 值较小比 42,没有数据被选中。
您可以参考 ASCII table 以获得更多理解:
仅当您使用 LIKE
运算符时才解释通配符。
因此,当您尝试与字符串进行比较时,它将按字面意思处理。所以在你的比较中使用了字典顺序。
1) *
之前没有字母,所以你没有返回任何行。
2) A
是字母表中的第一个字母,所以其余的名字 比 Abby 大 ,只有 Abby 等于它自己。
3) 与 2) 相对
4) 见 1)
5) 见 1)
6) 这个条件等价于Name = 'Abby'
.
通配符用于替换字符串中的任何其他字符。它们与 WHERE
子句中的 SQL LIKE
运算符一起使用。例如。
Select * from thisTable WHERE name LIKE '%Abby%'
这将 return 字符串中任意位置带有 Abby 的任何值。
查看此 link 以了解所有通配符的解释 https://www.w3schools.com/sql/sql_wildcards.asp
在 SQL 服务器中处理字符串时,对每个字母进行排序,这些字母的排序顺序取决于排序规则。对于某些字符,排序方法更容易理解,可以按字母顺序或数字顺序排列:例如'a' < 'b'
和'4' > '2'
。根据排序规则,这可能先字母后大小写 ('AaBbCc....'
) 或可能先字母后大小写 ('ABC...Zabc'
).
让我们拿一个像 'Abby'
这样的字符串,这将按字母 A、b、b、y 的顺序排序(它们出现的顺序将根据您的整理,我不我不知道它是什么,但我打算 假定 一个 'AaBbCc....'
排序规则,因为它们更常见)。任何以 'Aba'
开头的字符串都比 'Abby'
具有销售价值,因为第三个字符(第一个不同的字符)具有 "lower value"。就像 'Abbie'
这样的值('i'
的值低于 'y'
)。类似地,像 'Abc'
这样的字符串将具有更大的值,因为 'c'
具有比 'b'
更高的值(这是第一个不同的字符)。
如果我们将数字加入其中,您可能会感到惊讶。例如 string(重要的是,我没有说明数字)'123456789'
的 low 值比字符串 '9'
.这是因为第一个字符与第一个字符不同。 '9'
大于 '1'
,因此 '9'
具有 "higher" 值。这就是为什么确保将数字存储为数字数据类型如此重要的原因之一,因为这种行为不太可能是您 expect/want 否则的行为。
然而,根据您的要求,SQL 服务器的通配符是 '%'
和 '_'
(还有 '^'
,m 但我不会在这里覆盖)。 '%'
表示多个字符,而 '_'
表示单个字符。如果您想专门查找其中一个字符,则必须将它们用括号括起来 ([]
).
使用等号 (=
) 运算符不会解析通配符。你需要使用一个函数,比如 LIKE
。因此,如果您想要一个以 'A'
开头的单词,您可以使用表达式 WHERE ColumnName LIKE 'A%'
。如果您想搜索一个由 6 个字符组成并以 'ed'
结尾的字符,您可以使用 WHERE ColumnName LIKE '____ed'
.
就像我之前说的,如果你想搜索那些特定的字符之一,你就引用。因此,如果您想搜索包含下划线的字符串,则语法为 WHERE ColumnName LIKE '%[_]%'
编辑:还值得注意的是,当使用 LIKE
之类的东西时,它们会受到归类敏感性的影响;例如,大小写和口音。例如,如果您使用区分大小写的排序规则,则语句 WHERE 'Abby' LIKE 'abb%'
不正确,并且 'A'
和 'a'
不是相同的大小写。同样,语句 WHERE 'Covea' = 'Covéa'
在区分重音的排序规则中将是错误的('e'
和 'é'
不被视为相同的字符)。
有一些答案和一些评论 - 我会尝试总结一下。
首先,wildcard in SQL 是 %,而不是 *(对于多个匹配项)。因此,您的查询包括 * 要求与该文字字符串进行比较。
其次,比较字符串与 greater/less 比运算符可能不会做你想要的 - 它使用 collation order 来查看哪些其他字符串是 "earlier" 或 "later"在订购顺序中。归类顺序是一个中等复杂的概念,并且因机器安装而异。
SQL operator for string pattern matching 是 LIKE
。
我不确定我是否理解您使用 >=
或 <=
语句的意图 - 您的意思是您想要 return 名称第一个字母在 [ 之后的行=28=] 在字母表中?
假设我 table 看起来像这样:
Id | Name | Age
=====================
1 | Jose | 19
2 | Yolly | 26
20 | Abby | 3
29 | Tara | 4
而我的查询语句是:
1) Select * from thisTable where Name <= '*Abby';
它 returns 0 行
2) Select * from thisTable where Name <= 'Abby';
returns 与艾比
3) Select * from thisTable where Name >= 'Abby';
returns 所有行 // 第 1-4 行
4) Select * from thisTable where Name >= '*Abby';
returns 所有行; // 第 1-4 行
5) Select * from thisTable where Name >= '*Abby' and Name <= "*Abby";
returns 0 行。
6) Select * from thisTable where Name >= 'Abby' and Name <= 'Abby';
returns 与 Abby 并列;
我的问题:为什么我会得到这些结果?通配符如何影响查询结果?如果条件是 Name <= '*Abby'
为什么我得不到任何结果?
因为,>=
和<=
是比较运算符。他们根据 ASCII 值比较字符串。
因为ASCII值*是42和ASCII大写字母的值从65,这就是为什么当您尝试 name<='*Abby'
、sql-server 时选择字符串中第一个字符的 ASCII 值(即 42),因为数据中没有任何值的第一个字符 ASCII 值较小比 42,没有数据被选中。
您可以参考 ASCII table 以获得更多理解:
仅当您使用 LIKE
运算符时才解释通配符。
因此,当您尝试与字符串进行比较时,它将按字面意思处理。所以在你的比较中使用了字典顺序。
1) *
之前没有字母,所以你没有返回任何行。
2) A
是字母表中的第一个字母,所以其余的名字 比 Abby 大 ,只有 Abby 等于它自己。
3) 与 2) 相对
4) 见 1)
5) 见 1)
6) 这个条件等价于Name = 'Abby'
.
通配符用于替换字符串中的任何其他字符。它们与 WHERE
子句中的 SQL LIKE
运算符一起使用。例如。
Select * from thisTable WHERE name LIKE '%Abby%'
这将 return 字符串中任意位置带有 Abby 的任何值。
查看此 link 以了解所有通配符的解释 https://www.w3schools.com/sql/sql_wildcards.asp
在 SQL 服务器中处理字符串时,对每个字母进行排序,这些字母的排序顺序取决于排序规则。对于某些字符,排序方法更容易理解,可以按字母顺序或数字顺序排列:例如'a' < 'b'
和'4' > '2'
。根据排序规则,这可能先字母后大小写 ('AaBbCc....'
) 或可能先字母后大小写 ('ABC...Zabc'
).
让我们拿一个像 'Abby'
这样的字符串,这将按字母 A、b、b、y 的顺序排序(它们出现的顺序将根据您的整理,我不我不知道它是什么,但我打算 假定 一个 'AaBbCc....'
排序规则,因为它们更常见)。任何以 'Aba'
开头的字符串都比 'Abby'
具有销售价值,因为第三个字符(第一个不同的字符)具有 "lower value"。就像 'Abbie'
这样的值('i'
的值低于 'y'
)。类似地,像 'Abc'
这样的字符串将具有更大的值,因为 'c'
具有比 'b'
更高的值(这是第一个不同的字符)。
如果我们将数字加入其中,您可能会感到惊讶。例如 string(重要的是,我没有说明数字)'123456789'
的 low 值比字符串 '9'
.这是因为第一个字符与第一个字符不同。 '9'
大于 '1'
,因此 '9'
具有 "higher" 值。这就是为什么确保将数字存储为数字数据类型如此重要的原因之一,因为这种行为不太可能是您 expect/want 否则的行为。
然而,根据您的要求,SQL 服务器的通配符是 '%'
和 '_'
(还有 '^'
,m 但我不会在这里覆盖)。 '%'
表示多个字符,而 '_'
表示单个字符。如果您想专门查找其中一个字符,则必须将它们用括号括起来 ([]
).
使用等号 (=
) 运算符不会解析通配符。你需要使用一个函数,比如 LIKE
。因此,如果您想要一个以 'A'
开头的单词,您可以使用表达式 WHERE ColumnName LIKE 'A%'
。如果您想搜索一个由 6 个字符组成并以 'ed'
结尾的字符,您可以使用 WHERE ColumnName LIKE '____ed'
.
就像我之前说的,如果你想搜索那些特定的字符之一,你就引用。因此,如果您想搜索包含下划线的字符串,则语法为 WHERE ColumnName LIKE '%[_]%'
编辑:还值得注意的是,当使用 LIKE
之类的东西时,它们会受到归类敏感性的影响;例如,大小写和口音。例如,如果您使用区分大小写的排序规则,则语句 WHERE 'Abby' LIKE 'abb%'
不正确,并且 'A'
和 'a'
不是相同的大小写。同样,语句 WHERE 'Covea' = 'Covéa'
在区分重音的排序规则中将是错误的('e'
和 'é'
不被视为相同的字符)。
有一些答案和一些评论 - 我会尝试总结一下。
首先,wildcard in SQL 是 %,而不是 *(对于多个匹配项)。因此,您的查询包括 * 要求与该文字字符串进行比较。
其次,比较字符串与 greater/less 比运算符可能不会做你想要的 - 它使用 collation order 来查看哪些其他字符串是 "earlier" 或 "later"在订购顺序中。归类顺序是一个中等复杂的概念,并且因机器安装而异。
SQL operator for string pattern matching 是 LIKE
。
我不确定我是否理解您使用 >=
或 <=
语句的意图 - 您的意思是您想要 return 名称第一个字母在 [ 之后的行=28=] 在字母表中?