文章目录
- 写在前面
- 1.算数运算符
- 2.比较运算符
- 3.逻辑运算符
- 4.位运算符
- 5.运算符的优先级
- 拓展:使用正则表达式查询
写在前面
基本的运算符号在计算机编程领域都是相通的,会有自己的一些特定符号语言,就像是各地的普通话一样,尽管语音描述不一样,但大致的一样的可以作为理解的。了解一些计算规则有助于我们在进行sql脚本编写的时候经常排查,比如聚合是否包含null,字符串是否可以和数字进行计算等等~就怕业务统计的数据口径有差异,在进行数据建模的时候需要将数据进行二次加工(也可以加工后放到数据湖或者数据集市),咱们需要了解sql计算底层逻辑,因为在BI层面展示是尽量不会做过多的数据处理的(这样会导致BI服务器压力过大),BI层面可以暂时狭义的理解为数据展示层面,最终呈现的模样。
1.算数运算符
MySQL 的运算符及运算符的优先级。 MySQL 主要有以下几种运算符:
- 算术运算符
- 比较运算符
- 逻辑运算符
- 位运算符
算术运算符主要用于数学运算,其可以连接运算符前后的两个数值或表达式,对数值或表达式进行加
(+)、减(-)、乘(*)、除(/)和取模(%)运算。
运算符 | 作用 | 实例 |
---|---|---|
+ | 加法 | select a+b |
- | 减法 | select a-b |
* | 乘法 | select a*b |
/或者div | 除法 | select a/b 或者select a div b |
%或者MOD | 取余 | select a%b或者select a mod b |
在除法运算和模运算中,如果除数为0,将是非法除数,返回结果为NULL。
加减运算符
由运算结果可以得出如下结论:
- 一个整数类型的值对整数进行加法和减法操作,结果还是一个整数;
- 一个整数类型的值对浮点数进行加法和减法操作,结果是一个浮点数;
- 加法和减法的优先级相同,进行先加后减操作与进行先减后加操作的结果是一样的;
- 在Java中,+的左右两边如果有字符串,那么表示字符串的拼接。但是在MySQL中+只表示数值相加。如果遇到非数值类型,先尝试转成数值,如果转失败,就按0计算。(补充:MySQL中字符串拼接要使用字符串函数CONCAT()实现)
乘法钰除法运算符
求模运算
可以看到,100对3求模后的结果为3,对5求模后的结果为0。
由运算结果可以得出如下结论:
- 一个数乘以整数1和除以整数1后仍得原数;
- 一个数乘以浮点数1和除以浮点数1后变成浮点数,数值与原数相等;
- 一个数除以整数后,不管是否能除尽,结果都为一个浮点数;
- 一个数除以另一个数,除不尽时,结果为一个浮点数,并保留到小数点后4位;
- 乘法和除法的优先级相同,进行先乘后除操作与先除后乘操作,得出的结果相同。在数学运算中,0不能用作除数,在MySQL中,一个数除以0为NULL。
2.比较运算符
比较运算符是查询数据记录时经常使用的一类运算符。通过使用比较运算符可以判断出表中有哪些记录是符合条件的,如果比较的结果为真则返回1,如果为假则返回0,比较的结果如果不确定则返回NULL。其中字符串在进行比较的时候默认是不区分大小写的。
案例:
1、等于
等号运算符(=)判断等号两边的值、字符串或表达式是否相等,如果相等则返回1,不相等则返回0。
在使用等号运算符时,遵循如下规则:
- 如果等号两边的值、字符串或表达式都为字符串,则MySQL会按照字符串进行比较,其比较的是每个字符串中字符的ANSI编码是否相等。
- 如果等号两边的值都是整数,则MySQL会按照整数来比较两个值的大小。
- 如果等号两边的值一个是整数,另一个是字符串,则MySQL会将字符串转化为数字进行比较。
- 如果等号两边的值、字符串或表达式中有一个为NULL,则比较结果为NULL。 对比:SQL中赋值符号使用 :=
mysql> select 2=3;
+-----+
| 2=3 |
+-----+
| 0 |
+-----+
mysql> select NULL = NULL;
+-------------+
| NULL = NULL |
+-------------+
| NULL |
+-------------+
2、不等于
不等于运算符 不等于运算符(<>和!=)用于判断两边的数字、字符串或者表达式的值是否不相等,如果不相等则返回1,相等则返回0。不等于运算符不能判断NULL值。如果两边的值有任意一个为NULL,或两边都为NULL,则结果为NULL。 SQL语句示例如下:
mysql> select 2<>3;
+------+
| 2<>3 |
+------+
| 1 |
+------+
3、安全等于
与 = 的区别在于当两个操作码均为 NULL 时,其所得值为 1 而不为 NULL,而当一个操作码为 NULL 时,其所得值为 0而不为 NULL。
mysql> select 2<=>3;
+-------+
| 2<=>3 |
+-------+
| 0 |
+-------+
mysql> select null=null;
+-----------+
| null=null |
+-----------+
| NULL |
+-----------+
mysql> select null<=>null;
+-------------+
| null<=>null |
+-------------+
| 1 |
+-------------+
4、小于
mysql> select 2<3;
+-----+
| 2<3 |
+-----+
| 1 |
+-----+
5、小于等于
mysql> select 2<=3;
+------+
| 2<=3 |
+------+
| 1 |
+------+
6、大于
mysql> select 2>3;
+-----+
| 2>3 |
+-----+
| 0 |
+-----+
7、大于等于
mysql> select 2>=3;
+------+
| 2>=3 |
+------+
| 0 |
+------+
8、BETWEEN
mysql> select 5 between 1 and 10;
+--------------------+
| 5 between 1 and 10 |
+--------------------+
| 1 |
+--------------------+
9、IN
IN运算符用于判断给定的值是否是IN列表中的一个值,如果是则返回1,否则返回0。如果给定的值为NULL,或者IN列表中存在NULL,则结果为NULL。
mysql> select 5 in (1,2,3,4,5);
+------------------+
| 5 in (1,2,3,4,5) |
+------------------+
| 1 |
+------------------+
10、NOT IN
NOT IN运算符用于判断给定的值是否不是IN列表中的一个值,如果不是IN列表中的一个值,则返回1,否则返回0。
mysql> select 5 not in (1,2,3,4,5);
+----------------------+
| 5 not in (1,2,3,4,5) |
+----------------------+
| 0 |
+----------------------+
11、IS NULL
空运算符(IS NULL或者ISNULL)判断一个值是否为NULL,如果为NULL则返回1,否则返回
0。
mysql> select null is NULL;
+--------------+
| null is NULL |
+--------------+
| 1 |
+--------------+
mysql> select 'a' is NULL;
+-------------+
| 'a' is NULL |
+-------------+
| 0 |
+-------------+
12、IS NOT NULL
非空运算符(IS NOT NULL)判断一个值是否不为NULL,如果不为NULL则返回1,否则返
回0。
mysql> select null IS NOT NULL;
+------------------+
| null IS NOT NULL |
+------------------+
| 0 |
+------------------+
mysql> select 'a' IS NOT NULL;
+-----------------+
| 'a' IS NOT NULL |
+-----------------+
| 1 |
+-----------------+
13、LIKE
符 LIKE运算符主要用来匹配字符串,通常用于模糊匹配,如果满足条件则返回1,否则返回0。如果给定的值或者匹配条件为NULL,则返回结果为NULL。
mysql> select '12345' like '12%';
+--------------------+
| '12345' like '12%' |
+--------------------+
| 1 |
+--------------------+
mysql> select '12345' like '12_';
+--------------------+
| '12345' like '12_' |
+--------------------+
| 0 |
+--------------------+
14、REGEXP
```css
mysql> select 'beijing' REGEXP 'jing';
+-------------------------+
| 'beijing' REGEXP 'jing' |
+-------------------------+
| 1 |
+-------------------------+
mysql> select 'beijing' REGEXP 'xi';
+-----------------------+
| 'beijing' REGEXP 'xi' |
+-----------------------+
| 0 |
+-----------------------+
3.逻辑运算符
逻辑运算符又被称为布尔运算符,通常用来判断表达式的真假,如果为真返回1,否则返回0,真和假也可以用TRUE和FALSE表示。
MySQL中支持使用的逻辑运算符有四种
1表示为真TURE,0表示为假FALSE
逻辑非 1!= 0 0!= 1
真的为假,假的为真
逻辑与 0&&0=0 1&&0=0 0&&!=0 1&&1=1
两个条件都为真为真,两个为假为假
逻辑或 0||0=0 1||0=1 0||1=1 1||1=1
两个条件有一个为真则为真,两个为假为假
逻辑异或 0xor0=0 1xor0=1 0&&1=1 1xor1=0
两个条件一个为真即为真,两个为真或两个为假为假
1、与
mysql> select 2 and 0;
+---------+
| 2 and 0 |
+---------+
| 0 |
+---------+
mysql> select 2 and 1;
+---------+
| 2 and 1 |
+---------+
| 1 |
+---------+
2、或
mysql> select 2 or 0;
+--------+
| 2 or 0 |
+--------+
| 1 |
+--------+
mysql> select 2 or 1;
+--------+
| 2 or 1 |
+--------+
| 1 |
+--------+
mysql> select 0 or 0;
+--------+
| 0 or 0 |
+--------+
| 0 |
+--------+
mysql> select 1 || 0;
+--------+
| 1 || 0 |
+--------+
| 1 |
+--------+
3、非
mysql> select not 1;
+-------+
| not 1 |
+-------+
| 0 |
+-------+
mysql> select !0;
+----+
| !0 |
+----+
| 1 |
+----+
4、异或
mysql> select 1 xor 1;
+---------+
| 1 xor 1 |
+---------+
| 0 |
+---------+
mysql> select 0 xor 0;
+---------+
| 0 xor 0 |
+---------+
| 0 |
+---------+
mysql> select 1 xor 0;
+---------+
| 1 xor 0 |
+---------+
| 1 |
+---------+
mysql> select null or 1;
+-----------+
| null or 1 |
+-----------+
| 1 |
+-----------+
mysql> select 1 ^ 0;
+-------+
| 1 ^ 0 |
+-------+
| 1 |
+-------+
4.位运算符
位运算符实际上是对二进制数进行计算的运算符。
MySQL内位运算会先将操作数变成二进制格式,然后进行位运算,最后在将计算结果从二进制变回到十进制格式,方便用户查看。
MySQL支持6种位运算符
1、按位与
符 按位与(&)运算符将给定值对应的二进制数逐位进行逻辑与运算。当给定值对应的二进制位的数值都为1时,则该位返回1,否则返回0。
mysql> select 15&5,8|5,5^10,10&~1;
+------+-----+------+-------+
| 15&5 | 8|5 | 5^10 | 10&~1 |
+------+-----+------+-------+
| 5 | 13 | 15 | 10 |
+------+-----+------+-------+
1 row in set (0.00 sec)
运算过程 15&5 8|5 5^10 10&~1
第一步转换为二进制 15=1111 5=101 8=1000 5=101 5=101 10=1010 10=1010 1=1
第二步将二进制数一位一位对其进行运算符判断,对其方式为右对其向左补零。 ~1=1110
15=1111 8=1000 5=0101 10=1010
5=0101 5=0101 10=1010 ~1=1110
得到 0101=5 1101=13 1111=15 1010=10
- 按位与运算(&),是对应的二进制位都是1的,它们的运算结果为1,否则为0.
- 按位或运算(|),是对应的二进制位有一个或两个为1的,运算结果为1,否则为0.
- 按位异或运算(^),是对应的二进制位不相同时,运算结果1,否则为0.
- 按位取反(~),是对应的二进制数逐位反转,即1取反后变为0,0取反后变为1.通常结合其他的位运算一起使用,先对值取反在按另一个值补齐在进行其他的位运算符运算.
- 按位左移、右移
mysql> select 5<<2,2<<5,15>>3,25>>5;
+------+------+-------+-------+
| 5<<2 | 2<<5 | 15>>3 | 25>>5 |
+------+------+-------+-------+
| 20 | 64 | 1 | 0 |
+------+------+-------+-------+
1 row in set (0.00 sec)
向左位移过程 5<<2
转换为二进制 5=101
将5的二进制数整体向左移动两个位置空出来的补零得到 10100
转换为十进制为25
向右位移的过程 15>>3
转换为二进制 15=1111
将15的二进制数整体向右移动三个位置,移出的数丢弃得到 1
转换为十进制为1
注:左移或右移运算符,都是将数转换为二进制后,然后在左移或右移指定的位数,超出的位数将被移除并丢弃,空出来的位置用0补齐。
5.运算符的优先级
运算符,在使用过程中都有优先级问题。运算符的优先级决定了不同的运算符在计算过程中的先后顺序。级别高的运算符会先进行计算,如果运算符的级别相同,MySQL会按照顺序从左到右依次进行计算。如果不确定所使用的运算符的优先级,可以使用()改变优先级。
数字编号越大,优先级越高,优先级高的运算符先进行计算。可以看到,赋值运算符的优先级最低,使用“()”括起来的表达式的优先级最高
拓展:使用正则表达式查询
正则表达式通常被用来检索或替换那些符合某个模式的文本内容,根据指定的匹配模式匹配文本中符合要求的特殊字符串。例如,从一个文本文件中提取电话号码,查找一篇文章中重复的单词或者替换用户输入的某些敏感词语等,这些地方都可以使用正则表达式。正则表达式强大而且灵活,可以应用于非常复杂的查询。
MySQL中使用REGEXP关键字指定正则表达式的字符匹配模式。下表列出了REGEXP操作符中常用字符匹配列表。
- 查询以特定字符或字符串开头的记录 字符‘^’匹配以特定字符或者字符串开头的文本。
在fruits表中,查询f_name字段以字母‘b’开头的记录,SQL语句如下:
mysql> SELECT * FROM fruits WHERE f_name REGEXP '^b';
- 查询以特定字符或字符串结尾的记录 字符‘$’匹配以特定字符或者字符串结尾的文本。
在fruits表中,查询f_name字段以字母‘y’结尾的记录,SQL语句如下:
mysql> SELECT * FROM fruits WHERE f_name REGEXP 'y$';
3.用符号"."来替代字符串中的任意一个字符 字符‘.’匹配任意一个字符。 在fruits表中,查询f_name字段值包含字母‘a’与‘g’且两个字母之间只有一个字母的记录,SQL语句如下:
mysql> SELECT * FROM fruits WHERE f_name REGEXP 'a.g';
- 使用"“和”+"来匹配多个字符 星号‘’匹配前面的字符任意多次,包括0次。加号‘+’匹配前面的字符至
少一次。
在fruits表中,查询f_name字段值以字母‘b’开头且‘b’后面出现字母‘a’的记录,SQL语句如下:
mysql> SELECT * FROM fruits WHERE f_name REGEXP 'a.g';
在fruits表中,查询f_name字段值以字母‘b’开头且‘b’后面出现字母‘a’至少一次的记录,SQL语句如下:
mysql> SELECT * FROM fruits WHERE f_name REGEXP '^ba+';
- 匹配指定字符串 正则表达式可以匹配指定字符串,只要这个字符串在查询文本中即可,如要匹配多个字符串,多个字符串之间使用分隔符‘|’隔开。
在fruits表中,查询f_name字段值包含字符串“on”的记录,SQL语句如下:
mysql> SELECT * FROM fruits WHERE f_name REGEXP 'on';
在fruits表中,查询f_name字段值包含字符串“on”或者“ap”的记录,SQL语句如下:
mysql> SELECT * FROM fruits WHERE f_name like 'on';
Empty set(0.00 sec)
之前介绍过,LIKE运算符也可以匹配指定的字符串,但与REGEXP不同,LIKE匹配的字符串如果在文本中间出现,则找不到它,相应的行也不会返回。REGEXP在文本内进行匹配,如果被匹配的字符串在文本中出现,REGEXP将会找到它,相应的行也会被返回。对比结果如下所示。
在fruits表中,使用LIKE运算符查询f_name字段值为“on”的记录,SQL语句如下:
mysql> SELECT * FROM fruits WHERE f_name like 'on';
Empty set(0.00 sec)
- 匹配指定字符中的任意一个 方括号“[]”指定一个字符集合,只匹配其中任何一个字符,即为所查找的文本。
在fruits表中,查找f_name字段中包含字母‘o’或者‘t’的记录,SQL语句如下:
mysql> SELECT * FROM fruits WHERE f_name REGEXP '[ot]';
在fruits表中,查询s_id字段中包含4、5或者6的记录,SQL语句如下:
7. 匹配指定字符以外的字符 “[^字符集合]” 匹配不在指定集合中的任何字符。
在fruits表中,查询f_id字段中包含字母ae和数字12以外字符的记录,SQL语句如下:
mysql> SELECT * FROM fruits WHERE s_id REGEXP '[456]';
- 使用{n,}或者{n,m}来指定字符串连续出现的次数 “字符串{n,}”表示至少匹配n次前面的字符;“字符串{n,m}”表示匹配前面的字符串不少于n次,不多于m次。例如,a{2,}表示字母a连续出现至少2次,也可以大于2次;a{2,4}表示字母a连续出现最少2次,最多不能超过4次。
在fruits表中,查询f_name字段值出现字母‘x’至少2次的记录,SQL语句如下:
mysql> SELECT * FROM fruits WHERE f_name REGEXP 'x{2,}';
在fruits表中,查询f_name字段值出现字符串“ba”最少1次、最多3次的记录,SQL语句如下:
mysql> SELECT * FROM fruits WHERE f_name REGEXP 'ba{1,3}';