5.3 常见运算符介绍

5.3.1 运算符概述

运算符是告诉MySQL执行特定算术或逻辑操作的符号。MySQL的内部运算符很丰富,主要有四大类:算术运算符、比较运算符、逻辑运算符和位操作运算符。

1.算术运算符

算术运算符用于各类数值运算,包括加(+)、减(-)、乘(*)、除(/)、求余(或称模运算,%)。

2.比较运算符

比较运算符用于比较运算,包括大于(>)、小于(<)、等于(=)、大于等于(>=)、小于等于(<=)、不等于(!=)以及IN、BETWEEN AND、IS NULL、GREATEST、LEAST、LIKE、REGEXP等。

3.逻辑运算符

逻辑运算符的求值结果均为1(TRUE)、0(FALSE),这类运算符有逻辑非(NOT或者!)、逻辑与(AND 或者&&)、逻辑或(OR 或者||)、逻辑异或(XOR)。

4.位操作运算符

参与运算的操作数,按二进制位进行运算,包括位与(&)、位或(|)、位非(~)、位异或(^)、左移(<<)、右移(>>)6种。

接下来将对MySQL中的各种运算符的使用进行详细的介绍。

5.3.2 算术运算符

算术运算符是SQL中最基本的运算符,MySQL中的算术运算符如表5-10所示。

表5-10 MySQL中的算术运算符

下面分别讨论不同算术运算符的使用方法。

【例5.26】创建表tmp14,定义数据类型为INT的字段num,插入值64,对num值进行算术运算。

首先创建表tmp14,输入语句如下:

  CREATE TABLE tmp14 (num INT);

向字段num中插入数据64:

  INSERT INTO tmp14 value(64);

接下来,对num值进行加法和减法运算:

  mysql> SELECT num, num+10, num-3+5, num+5-3, num+36.5 FROM tmp14;
  +------+--------+---------+---------+----------+
  | num  | num+10 | num-3+5 | num+5-3 | num+36.5 |
  +------+--------+---------+---------+----------+
  |   64 |    74  |     66  |     66  |    100.5 |
  +------+--------+---------+---------+----------+
  1 row in set (0.00 sec)

由计算结果可以看到,可以对num字段的值进行加法和减法的运算,而且由于“+”和“–”的优先级相同,因此先加后减,或者先减后加之后的结果是相同的。

【例5.27】对tmp14表中的num字段进行乘除法运算。

  mysql> SELECT num, num *2, num /2, num/3, num%3 FROM tmp14;
  +------+--------+---------+---------+--------+
  | num  | num *2 | num /2  | num/3   | num%3  |
  +------+--------+---------+---------+--------+
  |   64 |   128  | 32.0000 | 21.3333 |    1   |
  +------+--------+---------+---------+--------+
  1 row in set (0.00 sec)

由计算结果可以看到,对num进行除法运算时,由于64无法被3整除,因此MySQL将num/3的结果保存到了小数点后面四位,结果为21.3333;64除以3的余数为1,因此取余运算num%3的结果为1。

在数学运算时,除数为0的除法是没有意义的,因此除法运算中的除数不能为0,如果被0除,则返回结果为NULL。

【例5.28】用0除num。

  mysql> SELECT num, num/0, num %0 FROM tmp14;
  +------+-------+--------+
  | num  | num/0 | num %0 |
  +------+-------+--------+
  |   64 |  NULL |  NULL   |
  +------+-------+--------+
  1 row in set (0.00 sec)

由计算结果可以看到,对num进行求商或者求余运算的结果均为NULL。

5.3.3 比较运算符

比较运算符的结果总是1、0或者NULL,比较运算符经常在SELECT的查询条件子句中使用,用来查询满足指定条件的记录。MySQL中的比较运算符如表5-11所示。

表5-11 MySQL中的比较运算符

下面讨论不同比较运算符的使用方法。

1.等于运算符(=)

等号(=)用来判断数字、字符串和表达式是否相等。如果相等,返回值为1,否则返回值为0。

【例5.29】使用“=”进行相等判断,SQL语句如下:

  mysql> SELECT 1=0, '2'=2, 2=2,'0.02'=0, 'b'='b', (1+3) = (2+2),NULL=NULL;
  +-----+-------+-----+----------+---------+---------------+------------+
  | 1=0 | '2'=2 | 2=2 | '0.02'=0 | 'b'='b' | (1+3) = (2+2) | NULL=NULL  |
  +-----+-------+-----+----------+---------+---------------+------------+
  |   0  |   1   |  1  |     0    |    1    |         1     |      NULL  |
  +-----+-------+-----+----------+---------+---------------+------------+
  1 row in set (0.00 sec)

由结果可以看到,在进行判断时,2=2和‘2’=2的返回值相同,都为1。因为在进行判断时,MySQL自动进行了转换,把字符‘2’转换成了数字2;‘b’=‘b’为相同的字符比较,因此返回值为1;表达式1+3和表达式2+2的结果都为4,因此结果相等,返回值为1;由于=不能用于空值NULL的判断,因此返回值为NULL。

数值比较时有如下规则:

(1)若有一个或两个参数为NULL,则比较运算的结果为NULL。

(2)若同一个比较运算中的两个参数都是字符串,则按照字符串进行比较。

(3)若两个参数均为整数,则按照整数进行比较。

(4)若一个字符串和数字进行相等判断,则MySQL可以自动将字符串转换为数字。

2.安全等于运算符(<=>)

这个操作符和=操作符执行相同的比较操作,不过<=>可以用来判断NULL值。在两个操作数均为NULL时,其返回值为1而不为NULL;而当一个操作数为NULL时,其返回值为0而不为NULL。

【例5.30】使用<=>进行相等的判断,SQL语句如下:

  mysql> SELECT 1<=>0, '2'<=>2, 2<=>2,'0.02'<=>0, 'b'<=>'b', (1+3) <=> (2+1),NULL<=>NULL;
  +------+--------+------+-----------+----------+----------------+------------+
  | 1<=>0 | '2'<=>2 | 2<=>2 | '0.02'<=>0 | 'b'<=>'b' | (1+3) <=> (2+1) | NULL<=>NULL |
  +------+--------+------+-----------+----------+----------------+------------+
  |    0  |      1 |    1  |        0   |      1    |            0    |          1 |
  +------+--------+------+-----------+----------+----------------+------------+
  1 row in set (0.00 sec)

由结果可以看到,<=>在执行比较操作时和=的作用是相似的,唯一的区别是<=>可以用来对NULL进行判断,两者都为NULL时返回值为1。

3.不等于运算符(<>或者!=)

<>或者!=用于数字、字符串、表达式不相等的判断。如果不相等,返回值为1;否则返回值为0。这两个运算符不能用于判断空值NULL。

【例5.31】使用<>和!=进行不相等的判断,SQL语句如下:

  mysql> SELECT 'good'<>'god', 1<>2, 4!=4, 5.5!=5, (1+3)!=(2+1),NULL<>NULL;
  +---------------+------+------+--------+--------------+-------------+
  | 'good'<>'god' | 1<>2 | 4!=4 | 5.5!=5 | (1+3)!=(2+1)| NULL<>NULL  |
  +---------------+------+------+--------+--------------+-------------+
  |        1      |   1  |   0  |    1   |        1     |       NULL  |
  +---------------+------+------+--------+--------------+-------------+
  1 row in set (0.00 sec)

由结果可以看到,两个不等于运算符的作用相同,都可以进行数字、字符串、表达式的比较判断。

4.小于或等于运算符(<=)

<=用来判断左边的操作数是否小于或者等于右边的操作数。如果小于或者等于,返回值为1,否则返回值为0。<=不能用于判断空值NULL。

【例5.32】使用<=进行比较判断,SQL语句如下:

  mysql>SELECT 'good'<='god', 1<=2, 4<=4, 5.5<=5, (1+3) <= (2+1),NULL<=NULL;
  +---------------+------+------+--------+---------------+--------------+
  | 'good'<='god' | 1<=2 | 4<=4 | 5.5<=5 | (1+3) <= (2+1)|   NULL<=NULL |
  +---------------+------+------+--------+---------------+--------------+
  |        0      |    1  |  1   |    0   |          0    |          NULL |
  +---------------+------+------+--------+---------------+--------------+
  1 row in set (0.00 sec)

由结果可以看到,左边操作数小于或者等于右边时,返回值为1,例如,4<=4;当左边的操作数大于右边时,返回值为0,例如,‘good’中第3个位置的o字符在字母表中的顺序大于‘god’中第3个位置d字符,因此返回值为0;同样比较NULL值时返回NULL。

5.小于运算符(<)

<运算符用来判断左边的操作数是否小于右边的操作数,如果小于,返回值为1;否则返回值为0。<不能用于判断空值NULL。

【例5.33】使用<进行比较判断,SQL语句如下:

  mysql> SELECT 'good'<'god', 1<2, 4<4, 5.5<5, (1+3) < (2+1),NULL<NULL;
  +--------------+------+-----+-------+---------------+-------------+
  | 'good'<'god' | 1<2  | 4<4 | 5.5<5 | (1+3) < (2+1) |   NULL<NULL |
  +--------------+------+-----+-------+---------------+-------------+
  |        0     |   1  |  0  |    0  |         0     |         NULL |
  +--------------+------+-----+-------+---------------+-------------+
  1 row in set (0.00 sec)

由结果可以看到,当左边的操作数小于右边时,返回值为1,例如,1<2;当左边的操作数大于右边时,返回值为0,例如,‘good’中第3个位置的o字符在字母表中的顺序大于‘god’中第3个位置的d字符,因此返回值为0;同样比较NULL值时返回NULL。

6.大于或等于运算符(>=)

>=运算符用来判断左边的操作数是否大于或者等于右边的操作数,如果大于或者等于,返回值为1;否则返回值为0。>=不能用于判断空值NULL。

【例5.34】使用>=进行比较判断,SQL语句如下:

  mysql> SELECT 'good'>='god', 1>=2, 4>=4, 5.5>=5, (1+3) >= (2+1),NULL>=NULL;
  +---------------+------+------+--------+---------------+--------------+
  | 'good'>='god' | 1>=2 | 4>=4 | 5.5>=5 | (1+3) >= (2+1)|   NULL>=NULL |
  +---------------+------+------+--------+---------------+--------------+
  |        1      |    0  |   1   |    1   |          1    |         NULL |
  +---------------+------+------+--------+---------------+--------------+
  1 row in set (0.00 sec)

由结果可以看到,左边的操作数大于或者等于右边时,返回值为1,例如,4>=4;当左边的操作数小于右边时,返回值为0,例如,1>=2;同样比较NULL值时返回NULL。

7.大于运算符(>)

>运算符用来判断左边的操作数是否大于右边的操作数,如果大于,返回值为1;否则返回值为0。>不能用于判断空值NULL。

【例5.35】使用>进行比较判断,SQL语句如下:

  mysql> SELECT 'good'>'god', 1>2, 4>4, 5.5>5, (1+3) > (2+1),NULL>NULL;
  +---------------+------+------+--------+---------------+-------------+
  | 'good'>'god'  | 1>2  | 4>4  | 5.5>5  | (1+3) > (2+1) |   NULL>NULL |
  +---------------+------+------+--------+---------------+-------------+
  |        1      |    0  |  0   |    1   |         1     |         NULL |
  +---------------+------+------+--------+---------------+-------------+
  1 row in set (0.00 sec)

由结果可以看到,左边的操作数大于右边时,返回值为1,例如,5.5>5;当左边的操作数小于右边时,返回值为0,例如,1>2;同样比较NULL值时返回NULL。

8.IS NULL(ISNULL)和IS NOT NULL运算符

IS NULL和ISNULL检验一个值是否为NULL,如果为NULL,返回值为1;否则返回值为0。IS NOT NULL检验一个值是否非NULL,如果非NULL,返回值为1;否则返回值为0。

【例5.36】使用IS NULL、ISNULL和IS NOT NULL判断NULL值和非NULL值,SQL语句如下:

  mysql> SELECT NULL IS NULL, ISNULL(NULL),ISNULL(10), 10 IS NOT NULL;
  +---------------+--------------+------------+----------------+
  | NULL IS NULL  | ISNULL(NULL) | ISNULL(10) | 10 IS NOT NULL |
  +---------------+--------------+------------+----------------+
  |           1   |           1  |        0   |            1    |
  +---------------+--------------+------------+----------------+
  1 row in set (0.00 sec)

由结果可以看到,IS NULL和ISNULL的作用相同,只是格式不同。ISNULL和IS NOT NULL的返回值正好相反。

9.BETWEEN AND运算符

语法格式为expr BETWEEN min AND max。假如expr大于或等于min且小于或等于max,则BETWEEN的返回值为1,否则返回值为0。

【例5.37】使用BETWEEN AND判断值区间,输入SQL语句如下:

  mysql> SELECT 4 BETWEEN 4 AND 6, 4 BETWEEN 4 AND 6,12 BETWEEN 9 AND 10;
  +------------------+-------------------+---------------------+
  | 4 BETWEEN 2 AND5 | 4 BETWEEN 4 AND 6 | 12 BETWEEN 9 AND 10 |
  +------------------+-------------------+---------------------+
  |               1  |               1   |                 0   |
  +------------------+-------------------+---------------------+
  1 row in set (0.00 sec)
  mysql> SELECT  'x' BETWEEN 'f' AND 'g', 'b' BETWEEN 'a' AND 'c';
  +-------------------------+-------------------------+
  | 'x' BETWEEN 'f' AND 'g' | 'b' BETWEEN 'a' AND 'c' |
  +-------------------------+-------------------------+
  |                  0       |                 1       |
  +-------------------------+-------------------------+
  1 row in set (0.00 sec)

由结果可以看到,4在端点值区间内或者等于其中一个端点值时,BETWEEN AND表达式的返回值为1;12并不在指定区间内,因此返回值为0。对于字符串,按字母表中的字母顺序进行比较,x不在指定的字母区间内,因此返回值为0,而b位于指定字母区间内,因此返回值为1。

10.LEAST运算符

语法格式为LEAST(值1,值2,...,值n),其中值n表示参数列表中有n个值。在有两个或多个参数的情况下,返回最小值。假如任意一个自变量为NULL,则LEAST()的返回值为NULL。

【例5.38】使用LEAST运算符进行大小判断,SQL语句如下:

  mysql> SELECT least(2,0), least(20.0,3.0,100.5), least('a','c','b'),
         least(10,NULL);
  +-------------+-----------------------+-------------------+-----------------+
  |  least(2,0) | least(20.0,3.0,100.5) | least('a','c','b') | least(10,NULL) |
  +-------------+-----------------------+-------------------+-----------------+
  |       0     |             3.0       | a                 |        NULL     |
  +-------------+-----------------------+-------------------+-----------------+
  1 row in set (0.00 sec)

由结果可以看到,当参数是整数或者浮点数时,LEAST将返回其中最小的值;当参数为字符串时,返回字母表中顺序最靠前的字符;当比较值列表中有NULL时,不能判断大小,返回值为NULL。

11.GREATEST (value1,value2,...)

语法格式为GREATEST(值1,值2,...,值n),其中n表示参数列表中有n个值。当有两个或多个参数时,返回值为最大值,假如任意一个自变量为NULL,则GREATEST()的返回值为NULL。

【例5.39】使用GREATEST运算符进行大小判断,SQL语句如下:

  mysql> SELECT greatest(2,0), greatest(20.0,3.0,100.5), greatest('a','c','b'),
         greatest(10,NULL);
  +---------------+--------------------------+-----------------------+-------------------+
  | greatest(2,0) | greatest(20.0,3.0,100.5) | greatest('a','c','b') | greatest(10,NULL) |
  +---------------+--------------------------+-----------------------+-------------------+
  |           2   |               100.5      | c                     |           NULL    |
  +---------------+--------------------------+-----------------------+-------------------+
  1 row in set (0.00 sec)

由结果可以看到,当参数是整数或者浮点数时,GREATEST将返回其中最大的值;当参数为字符串时,返回字母表中顺序最靠后的字符;当比较值列表中有NULL时,不能判断大小,返回值为NULL。

12.IN、NOT IN运算符

IN运算符用来判断操作数是否为IN列表中的一个值,如果是,返回值为1;否则返回值为0。

NOT IN运算符用来判断表达式是否不是IN列表中的一个值,如果不是,返回值为1;否则返回值为0。

【例5.40】使用IN、NOT IN运算符进行判断,SQL语句如下:

  mysql> SELECT 2 IN (1,3,5,'thks'), 'thks' IN (1,3,5,'thks');
  +---------------------+--------------------------+
  | 2 IN (1,3,5,'thks') | 'thks' IN (1,3,5,'thks') |
  +---------------------+--------------------------+
  |            0        |              1           |
  +---------------------+--------------------------+
  1 row in set, 2 warnings (0.00 sec)
  mysql> SELECT 2 NOT IN (1,3,5,'thks'), 'thks' NOT IN (1,3,5,'thks');
  +-------------------------+------------------------------+
  | 2 NOT IN (1,3,5,'thks') | 'thks' NOT IN (1,3,5,'thks') |
  +-------------------------+------------------------------+
  |                1        |                  0            |
  +-------------------------+------------------------------+
  1 row in set, 2 warnings (0.02 sec)

由结果可以看到,IN和NOT IN的返回值正好相反。

在左侧表达式为NULL的情况下,或是表中找不到匹配项并且表中有一个表达式为NULL的情况下,IN的返回值均为NULL。

【例5.41】存在NULL值时的IN查询,SQL语句如下:

  mysql> SELECT NULL IN (1,3,5,'thks'),10 IN (1,3,NULL,'thks');
  +------------------------+-------------------------+
  | NULL IN (1,3,5,'thks') | 10 IN (1,3,NULL,'thks') |
  +------------------------+-------------------------+
  |            NULL        |            NULL          |
  +------------------------+-------------------------+
  1 row in set, 1 warning (0.00 sec)

IN()语法也可用于在SELECT语句中进行嵌套子查询,在后面的章节中将会讲到。

13.LIKE

LIKE运算符用来匹配字符串,语法格式为“expr LIKE匹配条件”。如果expr满足匹配条件,则返回值为1(TRUE);如果不匹配,则返回值为0(FALSE)。若expr或匹配条件中任何一个为NULL,则结果为NULL。

LIKE运算符在进行匹配运算时,可以使用下面两种通配符。

(1)%:匹配任意数目的字符,甚至包括零字符。

(2)_:只能匹配一个字符。

【例5.42】使用运算符LIKE进行字符串匹配运算,SQL语句如下:

  mysql> SELECT 'stud' LIKE 'stud', 'stud' LIKE 'stu_','stud' LIKE '%d','stud' LIKE 't_ _ _', 's' LIKE NULL;
  +------------------+-----------------+----------------+---------------+-------------+
  |'stud' LIKE 'stud'|'stud' LIKE 'stu'|'stud' LIKE '%d'|'stud' LIKE 't'|'s' LIKE NULL|
  +------------------+-----------------+----------------+---------------+-------------+
  |            1     |            1    |             1   |            0  |       NULL  |
  +------------------+-----------------+----------------+---------------+-------------+
  1 row in set (0.00 sec)

由结果可以看到,指定匹配字符串为stud。stud表示直接匹配stud字符串,满足匹配条件,返回1;stu_表示匹配以stu开头的长度为4个字符的字符串,stud正好是4个字符,满足匹配条件,因此匹配成功,返回1;%d表示匹配以字母d结尾的字符串,stud满足匹配条件,匹配成功,返回1;t _ _ _表示匹配以t开头的长度为4个字符的字符串,stud不满足匹配条件,因此返回0;当字符s与NULL匹配时,结果为NULL。

14.REGEXP

REGEXP运算符用来匹配字符串,语法格式为“expr REGEXP匹配条件”。如果expr满足匹配条件,返回1;如果不满足,则返回0;若expr或匹配条件中任意一个为NULL,则结果为NULL。

REGEXP运算符在进行匹配运算时,常用的有下面几种通配符。

(1)^:匹配以该字符后面的字符开头的字符串。

(2)$:匹配以该字符后面的字符结尾的字符串。

(3).:匹配任何一个单字符。

(4)[...]:匹配在方括号内的任意字符。例如,[abc]匹配a、b或c。为了命名字符的范围,使用一个-。[a-z]匹配任意字母,而[0-9]匹配任意数字。

(5)*匹配零个或多个在它前面的字符。例如,x*匹配任意数量的x字符,[0-9]*匹配任意数量的数字,而.*匹配任意数量的任意字符。

【例5.43】使用运算符REGEXP进行字符串匹配运算,SQL语句如下:

  mysql> SELECT 'ssky' REGEXP '^s', 'ssky' REGEXP 'y$', 'ssky' REGEXP '.sky', 'ssky' REGEXP '[ab]';
  +--------------------+--------------------+----------------------+----------------------+
  | 'ssky' REGEXP '^s' | 'ssky' REGEXP 'y$' | 'ssky' REGEXP '.sky' | 'ssky' REGEXP '[ab]' |
  +--------------------+--------------------+----------------------+----------------------+
  |               1    |                1    |                 1    |                0     |
  +--------------------+--------------------+----------------------+----------------------+
  1 row in set (0.01 sec)

高街百年老店由结果可以看到,指定匹配字符串为ssky。^s表示匹配任意以字母s开头的字符串,因此满足匹配条件,返回1;y$表示任意以字母y结尾的字符串,因此满足匹配条件,返回1;.sky匹配任意以sky结尾,字符长度为4的字符串,满足匹配条件,返回1;[ab]匹配任意包含字母a或者b的字符串,指定字符串中没有字母a也没有字母b,因此不满足匹配条件,返回0。

提示 正则表达式是一个可以进行复杂查询的强大工具,相对于LIKE字符串匹配,它可以使用更多的通配符类型,查询结果更加灵活。读者可以参考相关的书籍或资料,详细学习正则表达式的写法,在这里就不详细介绍了。后面章节中,会介绍到如何使用正则表达式查询表中的记录。

5.3.4 逻辑运算符

在SQL中,所有逻辑运算符的求值结果均为TRUE、FALSE或NULL。在MySQL中,它们体现为1(TRUE)、0(FALSE)和NULL。MySQL中的逻辑运算符如表5-12所示。

表5-12 MySQL中的逻辑运算符

下面讨论逻辑运算符的使用方法。

1.NOT或者!

逻辑非运算符NOT或者!表示当操作数为0时,所得值为1;当操作数为非零值时,所得值为0;当操作数为NULL时,所得的返回值为NULL。

【例5.44】分别使用非运算符NOT和!进行逻辑判断,SQL语句如下:

  mysql>  SELECT NOT 10, NOT (1-1), NOT -5, NOT NULL, NOT 1 + 1;
  +--------+-----------+--------+----------+-----------+
  | NOT 10 | NOT (1-1) | NOT -5 | NOT NULL | NOT 1 + 1 |
  +--------+-----------+--------+----------+-----------+
  |     0  |       1   |     0  |    NULL  |       0   |
  +--------+-----------+--------+----------+-----------+
  1 row in set (0.00 sec)
  mysql>  SELECT !10, !(1-1), !-5, ! NULL, ! 1 + 1;
  +--------+-----------+--------+----------+-----------+
  | ! 10   | !  (1-1)  | !  -5  | !  NULL  | !  1 + 1  |
  +--------+-----------+--------+----------+-----------+
  |     0  |       1   |     0  |   NULL   |      1    |
  +--------+-----------+--------+----------+-----------+
  1 row in set (0.02 sec)
  mysql> SELECT ! 1+1;

由结果可以看到,前4列NOT和!的返回值都相同。但是注意最后1列,为什么会出现不同的值呢?这是因为NOT与!的优先级不同。NOT的优先级低于+,因此“NOT 1+1”相当于NOT(1+1),先计算1+1,然后再进行NOT运算,因为操作数不为0,因此NOT 1+1的结果是0;相反,由于!的优先级别要高于+运算,因此! 1+1相当于(!1)+1,先计算!1结果为0,再加1,最后结果为1。

提示 在使用运算符运算时,一定要注意不同运算符的优先级不同,如果不能确定计算顺序,最好使用括号,以保证运算结果的正确。

2.AND或者&&

逻辑与运算符AND或者&&表示当所有操作数均为非零值、并且不为NULL时,计算所得结果为1;当一个或多个操作数为0时,所得结果为0;其余情况返回值为NULL。

【例5.45】分别使用与运算符AND和&&进行逻辑判断,SQL语句如下:

  mysql> SELECT  1 AND -1,1 AND 0,1 AND NULL, 0 AND NULL;
  +----------+---------+------------+------------+
  | 1 AND -1 | 1 AND 0 | 1 AND NULL | 0 AND NULL |
  +----------+---------+------------+------------+
  |      1   |      0  |      NULL  |         0  |
  +----------+---------+------------+------------+
  1 row in set (0.00 sec)
  
  mysql> SELECT  1 && -1,1 && 0,1 && NULL, 0 && NULL;
  +----------+---------+------------+------------+
  | 1 && -1  | 1 && 0  | 1 && NULL  | 0 && NULL  |
  +----------+---------+------------+------------+
  |     1    |    0    |      NULL  |         0   |
  +----------+---------+------------+------------+
  1 row in set (0.00 sec) 

由结果可以看到,AND和&&的作用相同。“1 AND -1”中没有0或者NULL,因此结果为1;“1 AND 0”中有操作数0,因此结果为0;“1 AND NULL”中虽然有NULL,但是没有操作数0,返回结果为NULL。

提示 AND运算符可以有多个操作数,但要注意:有多个操作数运算时,AND两边一定要使用空格隔开,不然会影响结果的正确性。

3.OR或者||

逻辑或运算符OR和||表示当两个操作数均为非NULL值,且任意一个操作数为非零值时,结果为1,否则结果为0;当有一个操作数为NULL,且另一个操作数为非零值时,则结果为1,否则结果为NULL;当两个操作数均为NULL时,所得结果为NULL。

【例5.46】分别使用或运算符OR和||进行逻辑判断,SQL语句如下:

  mysql> SELECT  1 OR -1 OR 0, 1 OR 2,1 OR NULL, 0 OR NULL, NULL OR NULL;
  +--------------+--------+-----------+-----------+-------------+
  | 1 OR -1 OR 0 | 1 OR 2 | 1 OR NULL | 0 OR NULL | NULL OR NULL|
  +--------------+--------+-----------+-----------+-------------+
  |        1     |     1  |        1   |     NULL  |       NULL  |
  +--------------+--------+-----------+-----------+-------------+
  1 row in set (0.00 sec)
  
  mysql> SELECT  1 || -1 || 0, 1 || 2,1 || NULL, 0 || NULL, NULL || NULL;
  +----------------+----------+-----------+------------+--------------+
  |   1 || -1 || 0 |   1 || 2 | 1 || NULL |  0 || NULL |  NULL || NULL|
  +----------------+----------+-----------+------------+--------------+
  |        1       |      1    |      1    |     NULL   |        NULL  |
  +----------------+----------+-----------+------------+--------------+
  1 row in set (0.00 sec)

由结果可以看到,OR和||的作用相同。“1 OR -1 OR 0”中有0,但同时包含有非0的值1和-1,返回结果为1;“1 OR 2”中没有操作数0,返回结果为1;“1 OR NULL”中虽然有NULL,但是有操作数1,返回结果为1;“0 OR NULL”中没有非0值,并且有NULL,返回结果为NULL;“NULL OR NULL”中只有NULL,返回结果为NULL。

4.XOR

逻辑异或运算符XOR表示当任意一个操作数为NULL时,返回值为NULL;对于非NULL的操作数,如果两个操作数都是非0值或者都是0值,则返回结果为0;如果一个为0值,另一个为非0值,返回结果为1。

【例5.47】使用异或运算符XOR进行逻辑判断,SQL语句如下:

  SELECT 1 XOR 1, 0 XOR 0, 1 XOR 0, 1 XOR NULL, 1 XOR 1 XOR 1;

执行上面的语句,结果如下。

  mysql> SELECT 1 XOR 1, 0 XOR 0, 1 XOR 0, 1 XOR NULL, 1 XOR 1 XOR 1;
  +---------+---------+---------+------------+---------------+
  | 1 XOR 1 | 0 XOR 0 | 1 XOR 0 | 1 XOR NULL | 1 XOR 1 XOR 1 |
  +---------+---------+---------+------------+---------------+
  |      0  |      0  |     1   |      NULL  |           1   |
  +---------+---------+---------+------------+---------------+
  1 row in set (0.00 sec)

由结果可以看到,“1 XOR 1”和“0 XOR 0”中运算符两边的操作数都为非零值,或者都是零值,因此返回0;“1 XOR 0”中两边的操作数,一个为0值,另一个为非0值,返回结果为1;“1 XOR NULL”中有一个操作数为NULL,返回结果为NULL;“1 XOR 1 XOR 1”中有多个操作数,运算符相同,因此运算顺序从左到右依次计算,“1 XOR 1”的结果为0,再与1进行异或运算,因此结果为1。

提示 a XOR b的计算等同于(a AND (NOT b))或者((NOT a)AND b)。

5.3.5 位运算符

位运算符是用来对二进制字节中的位进行测试、移位或者测试处理,MySQL中提供的位运算符有按位或(|)、按位与(&)、按位异或(^)、按位左移(<<)、按位右移(>>)、按位取反(~),如表5-13所示。

表5-13 MySQL中的位运算符

下面讨论位运算符的使用方法。

1.位或运算符(|)

位或运算的实质是将参与运算的两个数据,按对应的二进制数逐位进行逻辑或运算。对应的二进制位有一个或两个为1则该位的运算结果为1,否则为0。

【例5.48】使用位或运算符进行运算,SQL语句如下:

  mysql> SELECT 10 | 15, 9 | 4 | 2;
  +----------+-----------+
  |  10 | 15 | 9 | 4 | 2 |
  +----------+-----------+
  |     15    |     15    |
  +----------+-----------+
  1 row in set (0.00 sec)

10的二进制数值为1010,15的二进制数值为1111,按位或运算之后,结果为1111,即整数15;9的二进制数值为1001,4的二进制数值为0100,2的二进制数值为0010,按位或运算之后,结果为1111,即也是整数15。其结果为一个64位无符号整数。

2.位与运算符(&)

位与运算的实质是将参与运算的两个操作数,按对应的二进制数逐位进行逻辑与运算。对应的二进制位都为1,则该位的运算结果为1,否则为0。

【例5.49】使用位与运算符进行运算,SQL语句如下:

  mysql> SELECT 10 & 15, 9 &4& 2;
  +---------+------------+
  |  10& 15 |  9 & 4 & 2 |
  +---------+------------+
  |    10   |         0  |
  +---------+------------+
  1 row in set (0.00 sec)

10的二进制数值为1010,15的二进制数值为1111,按位与运算之后,结果为1010,即整数10;9的二进制数值为1001,4的二进制数值为0100,2的二进制数值为0010,按位与运算之后,结果为0000,即整数0。其结果为一个64位无符号整数。

3.位异或运算符(^)

位异或运算的实质是将参与运算的两个数据,按对应的二进制数逐位进行逻辑异或运算。对应位的二进制数不同时,对应位的结果才为1;如果两个对应位数都为0或者都为1,则对应位的结果为0。

【例5.50】使用位异或运算符进行运算,SQL语句如下:

  mysql> SELECT 10 ^ 15, 1 ^0, 1 ^ 1;
  +---------+-----------+---------+
  |  10^ 15 |      1 ^0 |  1 ^ 1  |
  +---------+-----------+---------+
  |     5   |       1   |     0   |
  +---------+-----------+---------+
  1 row in set (0.00 sec)

10的二进制数值为1010,15的二进制数值为1111,按位与运算之后,结果为0101,即整数5;1的二进制数值为0001,0的二进制数值为0000,按位与运算之后,结果为0001;1和1本身二进制位完全相同,因此结果为0。

4.位左移运算符(<<)

位左移运算符可以使指定的二进制值的所有位都左移指定的位数。左移指定位数之后,左边高位的数值将被移出并丢弃,右边低位空出的位置用0补齐。语法格式为expr<<n。这里n表示值expr要移位的位数。

【例5.51】使用位左移运算符进行运算,SQL语句如下:

  mysql> SELECT 1<<2, 4<<2;
  +------+-------+
  | 1<<2 | 4<<2  |
  +------+-------+
  |   4  |  16   |
  +------+-------+

1的二进制值为0000 0001,左移两位之后变成0000 0100,即十进制整数4;十进制4左移两位之后变成0001 0000,即变成十进制的16。

5.位右移运算符(>>)

位右移运算符可以使指定的二进制值的所有位右移指定的位数。右移指定位数之后,右边低位的数值将被移出并丢弃,左边高位空出的位置用0补齐。语法格式为expr>>n。这里n表示值expr要移位的位数。

【例5.52】使用位右移运算符进行运算,SQL语句如下:

  mysql> SELECT 1>>1, 16>>2;
  +------+--------+
  | 1>>1 | 16>>2  |
  +------+--------+
  |   0  |    4   |
  +------+--------+

1的二进制值为0000 0001,右移1位之后变成0000 0000,即十进制整数0;16的二进制值为0001 0000,右移两位之后变成0000 0100,即变成十进制的4。

6.位取反运算符(~)

位取反运算的实质是将参与运算的数据,按对应的二进制数逐位反转,即1取反后变为0,0取反后变为1。

【例5.53】使用位取反运算符进行运算,SQL语句如下:

  mysql> SELECT 5 & ~1;
  +--------+
  | 5 & ~1 |
  +--------+
  |    4   |
  +--------+
  1 row in set (0.00 sec)

逻辑运算5&~1中,由于位取反运算符(~)的级别高于位与运算符(&),因此先对1取反操作,取反之后,只有最低位为0而其他位都为1,然后再与十进制数值5进行与运算,结果为0100,即整数4。

提示 在MySQL中,经过位运算之后的数值是一个64位的无符号整数。1的二进制数值只有最右边位为1,其他位均为0;取反操作之后,除了最低位,其他位均变为1。

可以使用BIN()函数查看1取反之后的结果,SQL语句如下:

  mysql> SELECT BIN(~1);
  +------------------------------------------------------------------+
  | BIN(~1)                                                          |
  +------------------------------------------------------------------+
  | 1111111111111111111111111111111111111111111111111111111111111110 |
  +------------------------------------------------------------------+
  1 row in set (0.00 sec)

这样,读者就可以明白例5.53是如何计算的了。

5.3.6 运算符的优先级

运算符的优先级决定了不同的运算符在表达式中计算的先后顺序,表5-14列出了MySQL中的各类运算符及其优先级,其中数值越大,优先级越高。

表5-14 运算符按优先级由低到高排列

不同运算符的优先级是不同的,一般情况下,级别高的运算符先进行计算,如果级别相同,MySQL按表达式的顺序从左到右依次计算。当然,在无法确定优先级的情况下,可以使用圆括号来改变优先级,并且这样会使计算过程更加清晰。