数据类型和运算符
-
- 1、MySQL数据类型介绍
- 2、如何选择数据类型
- 3、常见运算符介绍
-
- 3.1、运算符概述
- 3.2、算术运算符
- 3.3、比较运算符
-
- 3.3.1、等于运算符(=)
- 3.3.2、安全等于运算符(<=>)
- 3.3.3、不等于运算符(<>或者!=)
- 3.3.4、小于等于运算符(<=)
- 3.3.5、小于运算符(<)
- 3.3.6、大于等于运算符(>=)
- 3.3.7、大于运算符(>)
- [3.3.8、IS NULL(ISNULL)和IS NOT NULL运算符](#3.3.8、IS NULL(ISNULL)和IS NOT NULL运算符)
- [3.3.9、BETWEEN AND运算符](#3.3.9、BETWEEN AND运算符)
- 3.3.10、LEAST运算符
- 3.3.11、GREATEST (value1,value2,...)
- [3.3.12、IN、NOT IN运算符](#3.3.12、IN、NOT IN运算符)
- 3.3.13、LIKE
- 3.3.14、REGEXP
- 3.4、逻辑运算符
- 3.5、位运算符
- 3.6、运算符的优先级
- 4、综合案例------运算符的使用
- 5、常见问题
1、MySQL数据类型介绍
MySQL支持多种数据类型,主要有数值类型、日期/时间类型和字符串类型。
- 数值类型 :
- 整数类型
TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT - 浮点小数数据类型
FLOAT和DOUBLE - 定点小数类型
DECIMAL
- 整数类型
- 日期/时间类型 :包括
YEAR、TIME、DATE、DATETIME和TIMESTAMP - 字符串类型 :包括
CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET等。字符串类型又分为文本字符串和二进制字符串。
1.1、整数类型
数值型数据类型主要用来存储数字,MySQL提供了多种数值数据类型,不同的数据类型提供不同的取值范围,可以存储的值范围越大,其所需要的存储空间也会越大。MySQL主要提供的整数类型有TINYINT、SMALLINT、MEDIUMINT、INT(INTEGER)、BIGINT。整数类型的属性字段可以添加AUTO_INCREMENT自增约束条件。
下表列出了MySQL中的数值类型。

从表中可以看到,不同类型整数存储所需的字节数是不同的,占用字节数最小的是TINYINT类型,占用字节最大的是BIGINT类型,相应的占用字节越多的类型所能表示的数值范围越大。
根据占用字节数可以求出每一种数据类型的取值范围。例如,TINYINT需要1字节(8 bits)来存储,那么TINYINT无符号数的最大值为28-1(255)、TINYINT有符号数的最大值为27-1(127)。其他类型的整数的取值范围计算方法相同,如表所示。

有如下创建表的语句:
sql
create table tb_emp1
(
id int(11),
name varchar(25),
deptId int(11),
salary float
);
id字段的数据类型为INT(11),注意后面的数字11,它表示的是该数据类型指定的显示宽度,即能够显示的数值中数字的个数。例如,假设声明一个INT类型的字段:
sql
year int(4)
该声明指明,在year字段中的数据一般只显示4位数字的宽度。
显示宽度和数据类型的取值范围是无关的。显示宽度只是指明MySQL最大可能显示的数字个数,数值的位数小于指定的宽度时会由空格填充;如果插入了大于显示宽度的值,只要该值不超过该类型整数的取值范围,数值依然可以插入,而且能够显示出来。例如,向year字段插入一个数值19999,当使用SELECT查询该列值的时候,MySQL显示的将是完整的带有5位数字的19999,而不是4位数字的值。
其他整型数据类型也可以在定义表结构时指定所需要的显示宽度,如果不指定,则系统为每一种类型指定默认的宽度值,如例所示。
创建表tmp1,其中字段x、y、z、m、n数据类型依次为TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT,SQL语句如下:
sql
create table tmp1
(
x tinyint,
y smallint,
z mediumint,
m int,
n bigint
);
执行成功之后,使用DESC查看表结构,结果如下:
sql
desc tmp1;
+-------+-----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+---------+-------+
| x | tinyint | YES | | <null> | |
| y | smallint | YES | | <null> | |
| z | mediumint | YES | | <null> | |
| m | int | YES | | <null> | |
| n | bigint | YES | | <null> | |
+-------+-----------+------+-----+---------+-------+
可以看到,系统将添加不同的默认显示宽度。这些显示宽度能够保证显示每一种数据类型可以取到取值范围内的所有值。例如,TINYINT有符号数和无符号数的取值范围分别为-128127和0255,由于负号占了一个数字位,因此TINYINT默认的显示宽度为4。同理,其他整数类型的默认显示宽度与其有符号数的最小值的宽度相同。
不同的整数类型有不同的取值范围,并且需要不同的存储空间,因此应该根据实际需要选择最合适的类型,这样有利于提高查询的效率和节省存储空间。整数类型是不带小数部分的数值,现实生活中很多地方需要用到带小数的数值,下面将介绍MySQL中支持的小数类型。
显示宽度只用于显示,并不能限制取值范围和占用空间。例如:INT(3)会占用4字节的存储空间,并且允许的最大值不会是999,而是INT整型所允许的最大值。
1.2、浮点数类型和定点数类型
MySQL中使用浮点数和定点数来表示小数。
浮点数类型有两种:
- 单精度浮点类型(FLOAT)
- 双精度浮点类型(DOUBLE)
定点数类型只有一种:
- DECIMAL
浮点数类型和定点数类型都可以用(M,N)来表示。其中,M称为精度,表示总共的位数;N称为标度,表示小数的位数。
下表列出了MySQL中的小数类型和存储需求。

DECIMAL类型不同于FLOAT和DOUBLE,DECIMAL实际是以串存放的,可能的最大取值范围与DOUBLE一样,但是其有效的取值范围由M和D的值决定。如果改变M而固定D,则其取值范围将随M的变大而变大。
从表中可以看到,DECIMAL的存储空间并不是固定的,而由其精度值M决定的,占用M+2字节。
FLOAT类型的取值范围如下:
- 有符号的取值范围:-3.402823466E+38 ~-1.175494351E-38。
- 无符号的取值范围:0和1.175494351E-38 ~3.402823466E+38。
DOUBLE类型的取值范围如下:
- 有符号的取值范围:-1.7976931348623157E+308~ -2.2250738585072014E-308。
- 无符号的取值范围:0和2.2250738585072014E-308 ~1.7976931348623157E+308。
不论是定点数还是浮点数类型,如果用户指定的精度超出精度范围,则会四舍五入。
创建表tmp2,其中字段x、y、z的数据类型依次为FLOAT(5,1)、DOUBLE(5,1)和DECIMAL(5,1),向表中插入数据5.12、5.15和5.123,SQL语句如下:
sql
create table tmp2
(
x float(5, 1),
y double(5, 1),
z decimal(5, 1)
);
向表中插入数据:
sql
insert into tmp2 values(5.12, 5.15, 5.123);
Query OK, 1 row affected, 1 warning
Time: 0.082s
可以看到在插入数据时,MySQL给出了一个警告信息,使用SHOW WARNINGS;语句查看警告信息:
sql
show warnings;
+-------+------+----------------------------------------+
| Level | Code | Message |
+-------+------+----------------------------------------+
| Note | 1265 | Data truncated for column 'z' at row 1 |
+-------+------+----------------------------------------+
可以看到,FLOAT和DOUBLE在进行四舍五入时没有给出警告,只给出z字段数值被截断的警告。查看结果:
sql
select * from tmp2;
+-----+-----+-----+
| x | y | z |
+-----+-----+-----+
| 5.1 | 5.2 | 5.1 |
+-----+-----+-----+
FLOAT和DOUBLE在不指定精度时,默认会按照实际的精度(由计算机硬件和操作系统决定),DECIMAL若不指定精度则默认为(10,0)。
浮点数相对于定点数的优点是在长度一定的情况下,浮点数能够表示更大的数据范围;它的缺点是会引起精度问题。
在MySQL中,定点数以字符串形式存储,在对精度要求比较高的时候(如货币、科学数据等)使用DECIMAL的类型比较好,另外两个浮点数进行减法和比较运算时容易出问题,所以在使用浮点数时需要注意,并尽量避免做浮点数比较。
1.3、日期与时间类型
MySQL中有多种表示日期的数据类型,主要有DATETIME、DATE、TIMESTAMP、TIME和YEAR。
例如,当只记录年信息的时候,可以只使用YEAR类型,而没有必要使用DATE。每一个类型都有合法的取值范围,当指定确实不合法的值时系统将"零"值插入到数据库中。
下表列出了MySQL中的日期与时间类型。

1.3.1、YEAR
YEAR类型是一个单字节类型,用于表示年,在存储时只需要1字节。可以使用各种格式指定YEAR值,如下所示:
- 以4位字符串或者4位数字格式表示的YEAR,范围为'1901'~'2155'。输入格式为'YYYY'或者YYYY。例如,输入'2010'或2010,插入到数据库的值均为2010。
- 以2位字符串格式表示的YEAR,范围为'00'到'99'。'00'~'69'和'70'~'99'范围的值分别被转换为2000~2069和1970~1999范围的YEAR值。'0'与'00'的作用相同。插入超过取值范围的值将被转换为2000。
- 以2位数字表示的YEAR,范围为1~99。1~69和70~99范围的值分别被转换为2001~2069和1970~1999范围的YEAR值。注意:在这里0值将被转换为0000,而不是2000。
两位整数范围与两位字符串范围稍有不同。例如:插入2000年,读者可能会使用数字格式的0表示YEAR,实际上,插入数据库的值为0000,而不是所希望的2000。只有使用字符串格式的'0'或'00',才可以被正确地解释为2000。非法YEAR值将被转换为0000。
创建数据表tmp3,定义数据类型为YEAR的字段y,向表中插入值2010、'2010'、'2166',SQL语句如下:
首先创建表tmp3:
sql
create table tmp3
(
y year
);
向表中插入数据:
sql
insert into tmp3 values(2010), ('2010');
再次向表中插入数据:
sql
insert into tmp3 values('2166');
(1264, "Out of range value for column 'y' at row 1")
语句执行之后,MySQL给出了一条错误提示,可以看到,插入的第3个值2166超过了YEAR类型的取值范围,此时不能正常执行插入操作。
sql
select * from tmp3;
+------+
| y |
+------+
| 2010 |
| 2010 |
+------+
由结果可以看到,当插入值为数值类型的2010或者字符串类型的'2010'时,都正确地储存到了数据库中;而当插入值'2166'时,由于超出了YEAR类型的取值范围,因此,不能插入值。
向tmp3表中y字段插入2位字符串表示的YEAR值,分别为'0'、'00'、'77'和'10',SQL语句如下:
删除表中的数据:
sql
delete from tmp3;
向表中插入数据:
sql
INSERT INTO tmp3 values('0'),('00'),('77'),('10');
查看结果:
sql
select * from tmp3;
+------+
| y |
+------+
| 2000 |
| 2000 |
| 1977 |
| 2010 |
+------+
由结果可以看到,字符串'0'和'00'的作用相同,分别都转换成了2000年;'77'转换为1977;'10'转换为2010。
向tmp3表中y字段插入2位数字表示的YEAR值,分别为0、78和11,SQL语句如下:
删除表中的数据:
sql
DELETE FROM tmp3;
向表中插入数据:
sql
INSERT INTO tmp3 values(0),(78),(11);
查看结果:
sql
select * from tmp3;
+------+
| y |
+------+
| 0 |
| 1978 |
| 2011 |
+------+
由结果可以看到,0被转换为0000,78被转换为1978,11被转换为2011。
1.3.2、TIME
TIME类型用在只需要时间信息的值,在存储时需要3字节,格式为'HH:MM:SS'。其中,HH表示小时,MM表示分钟,SS表示秒。
TIME类型的取值范围为-838:59:59 ~838:59:59,小时部分会如此大的原因是TIME类型不仅可以用于表示一天的时间(必须小于24小时),还可能是某个事件过去的时间或两个事件之间的时间间隔(可以大于24小时,或者甚至为负)。可以使用各种格式指定TIME值。
- 'D HH:MM:SS'格式的字符串。可以使用下面任何一种"非严格"的语法:'HH:MM:SS'、'HH:MM'、'DHH:MM'、'D HH'或'SS'。这里的D表示日,可以取0~34之间的值。在插入数据库时,D被转换为小时保存,格式为"D*24+HH"。
- 'HHMMSS'格式的、没有间隔符的字符串或者HHMMSS格式的数值,假定是有意义的时间。例如:'101112'被理解为'10:11:12',但'109712'是不合法的(它有一个没有意义的分钟部分),存储时将变为 00:00:00。
为TIME列分配简写值时应注意:如果没有冒号,MySQL解释值时,假定最右边的两位表示秒。(MySQL解释TIME值为过去的时间而不是当天的时间。)例如,读者可能认为'1112'和1112表示11:12:00(11点12分),但MySQL将它们解释为00:11:12(11分12秒)。同样'12'和12被解释为00:00:12。相反,TIME值中如果使用冒号则肯定被看作当天的时间。也就是说,'11:12'表示11:12:00,而不是00:11:12。
创建数据表tmp4,定义数据类型为TIME的字段t,向表中插入值'10:05:05','23:23','2 10:10','302','10',SQL语句如下:
创建表tmp4:
sql
create table tmp4
(
t time
);
向表中插入数据:
sql
insert into tmp4 values('10:05:05'), ('23:23'), ('2 10:10'), ('302'), ('10');
查看结果:
sql
select * from tmp4;
+----------+
| t |
+----------+
| 10:05:05 |
| 23:23:00 |
| 58:10:00 |
| 00:03:02 |
| 00:00:10 |
+----------+
由结果可以看到,'10:05:05'被转换为10:05:05;'23:23'被转换为23:23:00;'210:10'被转换为58:10:00,'3 02'被转换为74:00:00;'10'被转换成00:00:10。
在使用'D HH'格式时,小时一定要使用双位数值,如果是小于10的小时数,应在前面加0。
向表tmp4中插入值'101112'、111213,'0'、107010,SQL语句如下:
删除表中的数据:
sql
delete from tmp4;
向表中插入数据:
sql
insert into tmp4 values('101112'), (111213), ('0');
再向表中插入数据:
sql
insert into tmp4 values (107010);
(1292, "Incorrect time value: '107010' for column 't' at row 1")
可以看到,在插入数据时,MySQL给出了一个错误提示信息,可以看到,第二次在插入记录的时候,数据超出了范围,原因是107010的分钟部分超过了60(分钟部分是不会超过60的)。
sql
select * from tmp4;
+----------+
| t |
+----------+
| 10:11:12 |
| 11:12:13 |
| 00:00:00 |
+----------+
由结果可以看到,'101112'被转换为10:11:12;111213被转换为11:12:13;'0'被转换为00:00:00;107010因为是不合法的值,因此不能被插入。
也可以使用系统日期函数向TIME字段列插入值。
向tmp4表中插入系统当前时间,SQL语句如下:
删除表中的数据:
sql
DELETE FROM tmp4;
向表中插入数据:
sql
insert into tmp4 values(current_time), (now());
查看结果:
sql
select * from tmp4;
+----------+
| t |
+----------+
| 18:23:03 |
| 18:23:03 |
+----------+
由结果可以看到,获取系统当前的日期时间插入到TIME类型的列t,因为读者输入语句的时间不确定,因此获取的值可能与这里的不同,但都是系统当前的日期时间值。
1.3.3、DATE类型
DATE类型用在仅需要日期值时,没有时间部分,在存储时需要3字节。日期格式为'YYYY-MM-DD'。其中,YYYY表示年,MM表示月,DD表示日。在给DATE类型的字段赋值时,可以使用字符串类型或者数字类型的数据插入,只要符合DATE的日期格式即可。
- 以'YYYY-MM-DD'或者'YYYYMMDD'字符串格式表示的日期,取值范围为'1000-01-01'~'9999-12-3'。例如,输入'2012-12-31'或者'20121231',插入数据库的日期都为2012-12-31。
- 以'YY-MM-DD'或者'YYMMDD'字符串格式表示的日期,在这里YY表示两位的年值。包含两位年值的日期会令人模糊,因为不知道世纪。MySQL使用以下规则解释两位年值:'00~69'范围的年值转换为'2000~2069';'70~99'范围的年值转换为'1970~1999'。例如,输入'12-12-31',插入数据库的日期为2012-12-31;输入'981231',插入数据的日期为1998-12-31。
- 以YY-MM-DD或者YYMMDD数字格式表示的日期,与前面相似,00~69范围的年值转换为2000~2069,70~99范围的年值转换为1970~1999。例如,输入12-12-31插入数据库的日期为2012-12-31;输入981231,插入数据的日期为1998-12-31。
- 使用CURRENT_DATE或者NOW(),插入当前系统日期。
创建数据表tmp5,定义数据类型为DATE的字段d,向表中插入"YYYY-MM-DD"和"YYYYMMDD"字符串格式日期,SQL语句如下:
sql
create table tmp5(d date);
insert into tmp5 values('1998-08-08'), ('19980808'), ('20101010');
select * from tmp5;
+------------+
| d |
+------------+
| 1998-08-08 |
| 1998-08-08 |
| 2010-10-10 |
+------------+
可以看到,各个不同类型的日期值都正确地插入到了数据表中。
向tmp5表中插入"YY-MM-DD"和"YYMMDD"字符串格式日期,SQL语句如下:
sql
delete from tmp5;
insert into tmp5 values('99-09-09'), ('990909'), ('000101'), ('111111');
select * from tmp5;
+------------+
| d |
+------------+
| 1999-09-09 |
| 1999-09-09 |
| 2000-01-01 |
| 2011-11-11 |
+------------+
向tmp5表中插入YYYYMMDD和YYMMDD数字格式日期,SQL语句如下:
sql
DELETE FROM tmp5;
INSERT INTO tmp5 values (19990909),(990909), ( 000101) ,( 111111);
select * from tmp5;
+------------+
| d |
+------------+
| 1999-09-09 |
| 1999-09-09 |
| 2000-01-01 |
| 2011-11-11 |
+------------+
向tmp5表中插入系统当前日期,SQL语句如下:
sql
DELETE FROM tmp5;
INSERT INTO tmp5 values( CURRENT_DATE() ),( NOW() );
select * from tmp5;
+------------+
| d |
+------------+
| 2026-06-22 |
| 2026-06-22 |
+------------+
CURRENT_DATE只返回当前日期值,不包括时间部分;NOW()函数返回日期和时间值,在保存到数据库时,只保留了其日期部分。
MySQL允许"不严格"语法:任何标点符号都可以用作日期部分之间的间隔符。例如,'98-11-31'、'98.11.31'、'98/11/31'和'98@11@31'是等价的,这些值也可以正确地插入到数据库中。
1.3.4、DATETIME
DATETIME类型用于需要同时包含日期和时间信息的值,在存储时需要8字节。日期格式为'YYYY-MM-DD HH:MM:SS'。其中,YYYY表示年,MM表示月,DD表示日,HH表示小时,MM表示分钟,SS表示秒。在给DATETIME类型的字段赋值时,可以使用字符串类型或者数字类型的数据插入,只要符合DATETIME的日期格式即可。
- 以
'YYYY-MM-DD HH:MM:SS'或者'YYYYMMDDHHMMSS'字符串格式表示的值,取值范围为'1000-01-0100:00:00'~'9999-12-3 23:59:59'。例如,输入'2012-12-31 05: 05: 05'或者'20121231050505',插入数据库的DATETIME值都为2012-12-31 05: 05: 05。 - 以
'YY-MM-DD HH:MM:SS'或者'YYMMDDHHMMSS'字符串格式表示的日期,在这里YY表示两位的年值。与前面相同,'00~69'范围的年值转换为'2000~2069','70~99'范围的年值转换为'1970~1999'。例如,输入'12-12-31 05: 05: 05',插入数据库的DATETIME为2012-12-31 05:05: 05;输入'980505050505',插入数据库的DATETIME为1998-05-05 05: 05:05。 - 以
YYYYMMDDHHMMSS或者YYMMDDHHMMSS数字格式表示的日期和时间。例如,输入20121231050505,插入数据库的DATETIME为2012-12-3105:05:05;输入981231050505,插入数据的DATETIME为1998-12-31 05: 05: 05。
创建数据表tmp6,定义数据类型为DATETIME的字段dt,向表中插入"YYYY-MM-DD HH:MM:SS"和"YYYYMMDDHHMMSS"字符串格式日期和时间值,SQL语句如下:
sql
create table tmp6(dt datetime);
insert into tmp6 values('1998-08-08 08:08:08'), ('19980808080808'), ('20101010101010');
select * from tmp6;
+---------------------+
| dt |
+---------------------+
| 1998-08-08 08:08:08 |
| 1998-08-08 08:08:08 |
| 2010-10-10 10:10:10 |
+---------------------+
可以看到,各个不同类型的日期值都正确地插入到了数据表中。
向tmp6表中插入"YY-MM-DDHH:MM:SS"和"YYMMDDHHMMSS"字符串格式日期和时间值,SQL语句如下:
sql
DELETE FROM tmp6;
insert into tmp6 values('99-09-09 09:09:09'), ('990909090909'), ('101010101010');
select * from tmp6;
+---------------------+
| dt |
+---------------------+
| 1999-09-09 09:09:09 |
| 1999-09-09 09:09:09 |
| 2010-10-10 10:10:10 |
+---------------------+
向tmp6表中插入YYYYMMDDHHMMSS和YYMMDDHHMMSS数字格式日期和时间值,SQL语句如下:
sql
DELETE FROM tmp6;
INSERT INTO tmp6 values(19990909090909), (101010101010);
select * from tmp6;
+---------------------+
| dt |
+---------------------+
| 1999-09-09 09:09:09 |
| 2010-10-10 10:10:10 |
+---------------------+
向tmp6表中插入系统当前日期和时间值,SQL语句如下:
sql
DELETE FROM tmp6;
INSERT INTO tmp6 values( NOW() );
select * from tmp6;
+---------------------+
| dt |
+---------------------+
| 2026-06-22 18:43:47 |
+---------------------+
NOW()函数返回当前系统的日期和时间值,格式为"YYYY-MM-DD HH:MM:SS"。
MySQL允许"不严格"语法:任何标点符号都可以用作日期部分或时间部分之间的间隔符。例如,'98-12-3111:30:45'、'98.12.3111+30+45'、'98/12/311130 45'和'98@12@31 113045'是等价的,这些值都可以正确地插入数据库。
1.3.5、TIMESTAMP
TIMESTAMP的显示格式与DATETIME相同,显示宽度固定在19个字符,日期格式为YYYY-MM-DD HH:MM:SS,在存储时需要4字节。
TIMESTAMP列的取值范围小于DATETIME的取值范围,为'1970-01-0100:00:01'UTC~'2038-01-1903:14:07'UTC。其中,UTC(CoordinatedUniversal Time)为世界标准时间,因此在插入数据时,要保证在合法的取值范围内。
创建数据表tmp7,定义数据类型为TIMESTAMP的字段ts,向表中插入 值'19950101010101'、'950505050505'、'1996-02-02 02:02:02'、'97@03@0303@03@03'、121212121212、NOW(),SQL语句如下:
sql
CREATE TABLE tmp7( ts TIMESTAMP);
insert into tmp7 values('19950101010101'),
('950505050505'),
('1996-02-02 02:02:02'),
('97@03@03 03@03@03'),
(121212121212),
(now());
select * from tmp7;
+---------------------+
| ts |
+---------------------+
| 1995-01-01 01:01:01 |
| 1995-05-05 05:05:05 |
| 1996-02-02 02:02:02 |
| 1997-03-03 03:03:03 |
| 2012-12-12 12:12:12 |
| 2026-06-22 18:49:57 |
+---------------------+
由结果可以看到,'19950101010101'被转换为1995-01-0101:01:01;'950505050505'被转换为1995-05-05 05:05:05;'1996-02-0202:02:02'被转换为1996-02-0202:02:02;'97@03@03 03@03@03'被转换为1997-03-03 03:03:03;121212121212被转换为2012-12-12 12:12:12;NOW()被转换为系统当前日期时间2018-11-0917:08:25。
TIMESTAMP与DATETIME除了存储字节和支持的范围不同外,还有一个最大的区别就是:DATETIME在存储日期数据时,按实际输入的格式存储,即输入什么就存储什么,与时区无关;而TIMESTAMP值的存储是以UTC(世界标准时间)格式保存的,存储时对当前时区进行转换,检索时再转换回当前时区。查询时,不同时区显示的时间值是不同的。
向tmp7表中插入当前日期,查看插入值,更改时区为东10区,再次查看插入值,SQL语句如下:
sql
DELETE FROM tmp7;
INSERT INTO tmp7 values( NOW() );
select * from tmp7;
+---------------------+
| ts |
+---------------------+
| 2026-06-22 18:51:10 |
+---------------------+
查询结果为插入时的日期值。所在时区一般为东8区,下面修改当前时区为东10区,SQL语句如下:
sql
set time_zone='+10:00';
再次查看插入时的日期值:
sql
select * from tmp7;
+---------------------+
| ts |
+---------------------+
| 2026-06-22 20:51:10 |
+---------------------+
由结果可以看到,因为东10区时间比东8区快2个小时,因此查询的结果经过时区转换之后,显示的值增加了2个小时。相同的,如果时区每减小一个值,则查询显示的日期中的小时数减1。
如果为一个DATETIME或TIMESTAMP对象分配一个DATE值,那么结果值的时间部分将被设置为'00:00:00',因为DATE值未包含时间信息。如果为一个DATE对象分配一个DATETIME或TIMESTAMP值,那么结果值的时间部分将被删除,因为DATE值未包含时间信息。
1.4、文本字符串类型
字符串类型用来存储字符串数据,除了可以存储字符串数据之外,还可以存储其他数据,比如图片和声音的二进制数据。MySQL支持两类字符型数据:文本字符串和二进制字符串。
文本字符串可以进行区分或者不区分大小写的串比较,还可以进行模式匹配查找。在MySQL中,文本字符串类型是指CHAR、VARCHAR、TEXT、ENUM和SET。
下表列出了MySQL中的文本字符串数据类型。

VARCHAR和TEXT类型与BLOB都是变长类型,其存储需求取决于列值的实际长度(在前面的表格中用L表示),而不是取决于类型的最大可能尺寸。例如,一个VARCHAR(10)列能保存最大长度为10个字符的字符串,实际的存储需要是字符串的长度L加上1字节(记录字符串的长度)。对于字符"abcd",L是4而存储要求是5字节。
1.4.1、CHAR和VARCHAR类型
CHAR(M)为固定长度字符串,在定义时指定字符串列长。当保存时在右侧填充空格,以达到指定的长度。M表示列长度,M的范围是0~255个字符。例如,CHAR(4)定义了一个固定长度的字符串列,其包含的字符个数最大为4。当检索到CHAR值时,尾部的空格将被删除。
VARCHAR(M)是长度可变的字符串,M表示最大列长度。M的范围是0~65535。VARCHAR的最大实际长度由最长的行的大小和使用的字符集确定,而其实际占用的空间为字符串的实际长度加1。例如,VARCHAR(50)定义了一个最大长度为50的字符串,如果插入的字符串只有10个字符,则实际存储的字符串为10个字符和一个字符串结束字符。VARCHAR在值保存和检索时尾部的空格仍保留。
下面将不同字符串保存到CHAR(4)和VARCHAR(4)列,说明CHAR和VARCHAR之间的差别,如表所示。

对比结果可以看到,CHAR(4)定义了固定长度为4的列,不管存入的数据长度为多少,所占用的空间均为4个字节;VARCHAR(4)定义的列所占的字节数为实际长度加1。
查询时,CHAR(4)和VARCHAR(4)的值并不一定相同,如下所示。
创建tmp8表,定义字段ch和vch数据类型依次为CHAR(4)、VARCHAR(4),向表中插入数据"ab ",SQL语句如下:
sql
create table tmp8
(
ch char(4),
vch varchar(4)
);
INSERT INTO tmp8 VALUES('ab ', 'ab ');
select concat('(', ch, ')'), concat('(', vch, ')')
from tmp8;
+----------------------+-----------------------+
| concat('(', ch, ')') | concat('(', vch, ')') |
+----------------------+-----------------------+
| (ab ) | (ab ) |
+----------------------+-----------------------+
从查询结果可以看到,ch在保存"ab "时将末尾的两个空格删除了,而vch字段保留了末尾的两个空格。
最后一行的值只有在使用"不严格"模式时,字符串才会被截断插入;如果MySQL运行在"严格"模式,超过列长度的值不会被保存,并且会出现错误信息"ERROR 1406(22001): Data too long for column",即字符串长度超过指定长度,无法插入。
1.4.2、TEXT类型
TEXT列保存非二进制字符串,如文章内容、评论等。当保存或查询TEXT列的值时,不删除尾部空格。Text类型分为4种:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。不同的TEXT类型的存储空间和数据长度不同。
TINYTEXT最大长度为255(28--1)字符的TEXT列。TEXT最大长度为65535(216--1)字符的TEXT列。MEDIUMTEXT最大长度为16777215(224--1)字符的TEXT列。LONGTEXT最大长度为4294967295(232--1)或4GB字符的TEXT列。
1.4.3、ENUM类型
ENUM是一个字符串对象,其值为表创建时在列规定中枚举的一列值。语法格式如下:
sql
字段名 ENUM('值1','值2',...,'值n')
其中,"字段名"指将要定义的字段,"值n"指枚举列表中的第n个值。ENUM类型的字段在取值时,只能在指定的枚举列表中取,而且一次只能取一个。创建的成员中有空格时,其尾部的空格将自动被删除。
ENUM值在内部用整数表示,并且每个枚举值均有一个索引值:列表值所允许的成员值从1开始编号,MySQL存储的就是这个索引编号。枚举最多可以有65535个元素。
例如,定义ENUM类型的列('first','second','third'),该列可以取的值和每个值的索引如表所示。

ENUM值依照列索引顺序排列,并且空字符串排在非空字符串前,NULL值排在其他所有的枚举值前。
在这里,有一个方法可以查看列成员的索引值,如下所示。
创建表tmp9,定义ENUM类型的列enm('first','second','third'),查看列成员的索引值,SQL语句如下:
sql
CREATE TABLE tmp9
(
enm ENUM('first','second','third')
);
INSERT INTO tmp9 values('first'),('second') ,('third') , (NULL);
select enm, enm + 0
from tmp9;
+--------+---------+
| enm | enm + 0 |
+--------+---------+
| first | 1.0 |
| second | 2.0 |
| third | 3.0 |
| <null> | <null> |
+--------+---------+
可以看到,这里的索引值和前面所述的相同。
ENUM列总有一个默认值:如果将ENUM列声明为NULL,NULL值则为该列的一个有效值,并且默认值为NULL;如果ENUM列被声明为NOT NULL,其默认值为允许的值列表的第1个元素。
创建表tmp10,定义INT类型的soc字段,ENUM类型的字段level,并且列表值为('excellent','good', 'bad'),向表tmp10中插入数据(70,'good')、(90,1)、(75,2)、(50,3)、(100,'best'),SQL语句如下:
sql
CREATE TABLE tmp10
(
soc INT,
level enum('excellent', 'good','bad')
);
INSERT INTO tmp10 values(70,'good'), (90,1),(75,2),(50,3);
再次插入数据:
sql
INSERT INTO tmp10 values (100,'best');
(1265, "Data truncated for column 'level' at row 1")
这里系统提示错误信息,可以看到,由于字符串值'best'不在ENUM列表中,所以对数据进行了阻止插入操作,查询结果如下:
sql
select * from tmp10;
+-----+-----------+
| soc | level |
+-----+-----------+
| 70 | good |
| 90 | excellent |
| 75 | good |
| 50 | bad |
+-----+-----------+
由结果可以看到,因为ENUM列表中的值在MySQL中都是以编号序列存储的,所以插入列表中的值"good"或者插入其对应序号'2'的结果是相同的。"best"不是列表中的值,因此不能插入数据。
1.4.4、SET类型
SET是一个字符串对象,可以有零或多个值。SET列最多可以有64个成员,其值为表创建时规定的一列值。指定包括多个SET成员的SET列值时,各成员之间用逗号(,)间隔开。语法格式如下:
sql
SET('值1','值2',...,'值n')
与ENUM类型相同,SET值在内部用整数表示,列表中每一个值都有一个索引编号。当创建表时,SET成员值的尾部空格将自动被删除。与ENUM类型不同的是,ENUM类型的字段只能从定义的列值中选择一个值插入,而SET类型的列可从定义的列值中选择多个字符的联合。
- 如果插入SET字段中列值有重复,则MySQL自动删除重复的值;
- 插入SET字段的值的顺序并不重要,MySQL会在存入数据库时按照定义的顺序显示;
- 如果插入了不正确的值,默认情况下,MySQL将忽视这些值,并给出警告。
创建表tmp11,定义SET类型的字段s,取值列表为('a', 'b', 'c', 'd'),插入数据('a')、('a,b,a')、('c,a,d')、('a,x,b,y'),SQL语句如下:
sql
CREATE TABLE tmp11
(
s SET('a', 'b', 'c', 'd')
);
INSERT INTO tmp11 values('a'),( 'a,b,a'),('c,a,d');
INSERT INTO tmp11 values ('a,x,b,y');
(1265, "Data truncated for column 's' at row 1")
由于插入了SET列不支持的值,因此MySQL给出错误提示。
sql
select * from tmp11;
+-------+
| s |
+-------+
| a |
| a,b |
| a,c,d |
+-------+
从结果可以看到,对于SET来说,如果插入的值为重复的,则只取一个,例如插入"a,b,a",则结果为"a,b";如果插入了不按顺序排列的值,则自动按顺序插入,例如插入"c,a,d",结果为"a,c,d";如果插入了不正确的值,那么该值将被阻止插入,例如插入值"a,x,b,y"。
1.5、二进制字符串类型
MySQL中的二进制数据类型有BIT、BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。
下表列出了MySQL中的二进制数据类型。

1.5.1、BIT类型
BIT类型是位字段类型。
- M表示每个值的位数,范围为1~64。
- 如果M被省略,默认为1。
- 如果为BIT(M)列分配的值的长度小于M位,就在值的左边用0填充。
例如,为BIT(6)列分配一个值b'101',其效果与分配b'000101'相同。
BIT数据类型用来保存位字段值。例如,以二进制的形式保存数据13(13的二进制形式为1101),在这里需要位数至少为4位的BIT类型,即可以定义列类型为BIT(4),大于二进制1111的数据是不能插入BIT(4)类型的字段中的。
创建表tmp12,定义BIT(4)类型的字段b,向表中插入数据2、9、15。
sql
CREATE TABLE tmp12( b BIT(4) );
INSERT INTO tmp12 VALUES(2), (9), (15);
select bin(b+0) from tmp12;
+----------+
| bin(b+0) |
+----------+
| 10 |
| 1001 |
| 1111 |
+----------+
b+0表示将二进制的结果转换为对应的数字的值,BIN()函数将数字转换为二进制。从结果可以看到,成功地将3个数插入表中。
默认情况下,MySQL不可以插入超出该列允许范围的值,因而插入的数据要确保插入的值在指定的范围内。
1.5.2、BINARY和VARBINARY类型
BINARY和VARBINARY类型类似于CHAR和VARCHAR,不同的是它们包含二进制字节字符串。其使用的语法格式如下:
sql
列名称 BINARY(M)或者VARBINARY(M)
BINARY类型的长度是固定的,指定长度之后,不足最大长度的,将在它们右边填充'\0'补齐以达到指定长度。
例如:指定列数据类型为BINARY(3),当插入'a'时,存储的内容实际为"a\0\0",当插入"ab"时,实际存储的内容为"ab\0",不管存储的内容是否达到指定的长度,其存储空间均为指定的值M。
VARBINARY类型的长度是可变的,指定好长度之后,其长度可以在0到最大值之间。
例如:指定列数据类型为VARBINARY(20),如果插入的值的长度只有10,则实际存储空间为10加1,即实际占用的空间为字符串的实际长度加1。
创建表tmp13,定义BINARY(3)类型的字段b和VARBINARY(3)类型的字段vb,并向表中插入数据'5',比较两个字段的存储空间。
sql
CREATE TABLE tmp13 (
b BINARY(3),
vb VARBINARY(3)
);
INSERT INTO tmp13 VALUES(5,5);
查看两个字段存储数据的长度:
sql
select length(b), length(vb)
from tmp13;
+-----------+------------+
| length(b) | length(vb) |
+-----------+------------+
| 3 | 1 |
+-----------+------------+
可以看到,b字段的值数据长度为3,而vb字段的数据长度仅为插入的一个字符的长度1。
1.5.3、BLOB类型
BLOB是一个二进制大对象,用来存储可变数量的数据。BLOB类型分为4种:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB,它们可容纳值的最大长度不同,如表所示。

BLOB列存储的是二进制字符串(字节字符串),TEXT列存储的是非二进制字符串(字符字符串)。BLOB列没有字符集,并且排序和比较基于列值字节的数值;TEXT列有一个字符集,并且根据字符集对值进行排序和比较。
2、如何选择数据类型
MySQL提供了大量的数据类型,为了优化存储、提高数据库性能,在任何情况下均应使用最精确的类型,即在所有可以表示该列值的类型中,该类型使用的存储最少。
2.1、整数和浮点数
- 如果不需要小数部分,就使用整数来保存数据;
- 如果需要表示小数部分,就使用浮点数类型。
对于浮点数据列,存入的数值会对该列定义的小数位进行四舍五入。
例如,假设列的值的范围为1~99999,若使用整数,则MEDIUMINT UNSIGNED是最好的类型;若需要存储小数,则使用FLOAT类型。
浮点类型包括FLOAT和DOUBLE类型。DOUBLE类型精度比FLOAT类型高,因此要求存储精度较高时应选择DOUBLE类型。
2.2、浮点数和定点数
浮点数FLOAT、DOUBLE相对于定点数DECIMAL的优势是:在长度一定的情况下,浮点数能表示更大的数据范围。由于浮点数容易产生误差,因此对精确度要求比较高时,建议使用DECIMAL来存储。
DECIMAL在MySQL中是以字符串存储的,用于定义货币等对精确度要求较高的数据。在数据迁移中,float(M,D)是非标准SQL定义,数据库迁移可能会出现问题,最好不要这样使用。
另外,两个浮点数进行减法和比较运算时也容易出问题,因此在进行计算的时候,一定要小心。进行数值比较时,最好使用DECIMAL类型。
2.3、日期与时间类型
MySQL对于不同种类的日期和时间有很多数据类型,比如YEAR和TIME。如果只需要记录年份,则使用YEAR类型即可;如果只记录时间,则使用TIME类型。
如果同时需要记录日期和时间,则可以使用TIMESTAMP或者DATETIME类型。由于TIMESTAMP列的取值范围小于DATETIME的取值范围,因此存储范围较大的日期最好使用DATETIME。
TIMESTAMP也有一个DATETIME不具备的属性。默认的情况下,当插入一条记录但并没有指定TIMESTAMP这个列值时,MySQL会把TIMESTAMP列设为当前的时间。因此当需要插入记录的同时插入当前时间时,使用TIMESTAMP是方便的。另外,TIMESTAMP在空间上比DATETIME更有效。
2.4、CHAR与VARCHAR之间的特点与选择
CHAR和VARCHAR的区别如下:
- CHAR是固定长度字符,VARCHAR是可变长度字符。
- CHAR会自动删除插入数据的尾部空格,VARCHAR不会删除尾部空格。
CHAR是固定长度,所以它的处理速度比VARCHAR的速度要快,但是它的缺点是浪费存储空间,所以对存储不大但在速度上有要求的可以使用CHAR类型,反之可以使用VARCHAR类型来实现。
存储引擎对于选择CHAR和VARCHAR的影响:
- 对于MyISAM存储引擎:最好使用固定长度的数据列代替可变长度的数据列。这样可以使整个表静态化,从而使数据检索更快,用空间换时间。
- 对于InnoDB存储引擎:使用可变长度的数据列,因为InnoDB数据表的存储格式不分固定长度和可变长度,因此使用CHAR不一定比使用VARCHAR更好,但由于VARCHAR是按照实际的长度存储的,比较节省空间,所以对磁盘I/O和数据存储总量比较好。
2.5、ENUM和SET
ENUM只能取单值,它的数据列表是一个枚举集合。它的合法取值列表最多允许有65535个成员。因此,在需要从多个值中选取一个时,可以使用ENUM。比如:性别字段适合定义为ENUM类型,每次只能从'男'或'女'中取一个值。
SET可取多值。它的合法取值列表最多允许有64个成员。空字符串也是一个合法的SET值。在需要取多个值的时候,适合使用SET类型,比如要存储一个人的兴趣爱好,最好使用SET类型。
ENUM和SET的值是以字符串形式出现的,但在内部,MySQL是以数值的形式存储它们的。
2.6、BLOB和TEXT
BLOB是二进制字符串,TEXT是非二进制字符串,两者均可存放大容量的信息。
- BLOB主要存储图片、音频信息等
- TEXT只能存储纯文本文件
3、常见运算符介绍
运算符连接表达式中的各个操作数,其作用是用来指明对操作数所进行的运算。运用运算符可以更加灵活地使用表中的数据,常见的运算符类型有算术运算符、比较运算符、逻辑运算符和位运算符。
3.1、运算符概述
运算符是告诉MySQL执行特定算术或逻辑操作的符号。MySQL的内部运算符很丰富,主要有四大类,分别是算术运算符、比较运算符、逻辑运算符、位运算符。
- 算术运算符
算术运算符用于各类数值运算,包括加(+)、减(-)、乘(*)、除(/)、求余(或称模运算,%)。 - 比较运算符
比较运算符用于比较运算,包括大于(>)、小于(<)、等于(=)、大于等于(>=)、小于等于(<=)、不等于(!=),以及IN、BETWEEN AND、IS NULL、GREATEST、LEAST、LIKE、REGEXP等。 - 逻辑运算符
逻辑运算符的求值所得结果均为1(TRUE)、0(FALSE),这类运算符有逻辑非(NOT或者!)、逻辑与(AND或者&&)、逻辑或(OR或者||)、逻辑异或(XOR)。 - 位运算符
位运算符参与运算的操作数按二进制位进行运算,包括位与(&)、位或(|)、位非(~)、位异或(^)、左移(<<)、右移(>>)6种。
3.2、算术运算符
算术运算符是SQL中最基本的运算符。MySQL中的算术运算符如表所示。

创建表tmp14,定义数据类型为INT的字段num,插入值64,对num值进行算术运算。
sql
CREATE TABLE tmp14 ( num INT);
INSERT INTO tmp14 value(64);
对num值进行加法和减法运算:
sql
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 |
+-----+--------+---------+---------+----------+
由计算结果可以看到,可以对num字段的值进行加法和减法的运算,而且'+'和'--'的优先级相同,先加后减或者先减后加的结果是相同的。
对tmp14表中的num进行乘法、除法运算。
sql
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 |
+-----+-------+---------+---------+-------+
由计算结果可以看到,对num进行除法运算的时候,64无法被3整除,MySQL对num/3求商的结果保存到了小数点后面四位,结果为21.3333;64除以3的余数为1,因此取余运算num%3的结果为1。
在数学运算时,除数为0的除法是没有意义的,因此除法运算中的除数不能为0,如果被0除,则返回结果为NULL。
用0除num。
sql
select num, num/0, num%0
from tmp14;
+-----+--------+--------+
| num | num/0 | num%0 |
+-----+--------+--------+
| 64 | <null> | <null> |
+-----+--------+--------+
由计算结果可以看到,对num进行除法求商或者求余运算的结果均为NULL。
3.3、比较运算符
一个比较运算符的结果总是1、0或者是NULL。比较运算符经常在SELECT的查询条件子句中使用,用来查询满足指定条件的记录。
MySQL中的比较运算符如表所示。

3.3.1、等于运算符(=)
等号(=)用来判断数字、字符串和表达式是否相等:如果相等,返回值为1;否则返回值为0。
使用'='进行相等判断,SQL语句如下:
sql
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> |
+-----+-------+-----+----------+---------+-------------+-----------+
由结果可以看到,在进行判断时,2=2和'2'=2的返回值相同,都为1。因为在进行判断时,MySQL自动进行了转换,把字符'2'转换成了数字2;'b'='b'为相同的字符比较,因此返回值为1;表达式1+3和表达式2+2的结果都为4,因此结果相等,返回值为1;由于'='不能用于空值NULL的判断,因此返回值为NULL。
数值比较时有如下规则:
- 若有一个或两个参数为NULL,则比较运算的结果为NULL。
- 若同一个比较运算中的两个参数都是字符串,则按照字符串进行比较。
- 若两个参数均为整数,则按照整数进行比较。
- 若用字符串和数字进行相等判断,则MySQL可以自动将字符串转换为数字。
3.3.2、安全等于运算符(<=>)
这个操作符和=操作符执行相同的比较操作,不过<=>可以用来判断NULL值。在两个操作数均为NULL时,其返回值为1,而不为NULL;当一个操作数为NULL时,其返回值为0,而不为NULL。
使用'<=>'进行相等的判断,SQL语句如下:
sql
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 |
+-------+---------+-------+------------+-----------+-----------------+---------------+
由结果可以看到,'<=>'在执行比较操作时和'='的作用是相似的,唯一的区别是'<=>'可以用来对NULL进行判断,两者都为NULL时返回值为1。
3.3.3、不等于运算符(<>或者!=)
'<>'或者'!='用于判断数字、字符串、表达式不相等的判断:如果不相等,返回值为1;否则返回值为0。这两个运算符不能用于判断空值NULL。
使用'<>'和'!='进行不相等的判断,SQL语句如下:
sql
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> |
+---------------+------+------+--------+--------------+------------+
由结果可以看到,两个不等于运算符的作用相同,都可以进行数字、字符串、表达式的比较判断。
3.3.4、小于等于运算符(<=)
'<='用来判断左边的操作数是否小于等于右边的操作数:如果小于等于,返回值为1;否则返回值为0。'<='不能用于判断空值NULL。
使用'<='进行比较判断,SQL语句如下:
sql
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,例如4<=4;当左边操作数大于右边时,返回值为0,例如'good'<='god'('good'第3个位置的'o'字符在字母表中的顺序大于'god'中第3个位置的'd'字符,因此返回值为0);同样比较NULL值时返回NULL。
3.3.5、小于运算符(<)
'<'运算符用来判断左边的操作数是否小于右边的操作数:如果小于,返回值为1;否则返回值为0。'<'不能用于判断空值NULL。
使用'<'进行比较判断,SQL语句如下:
sql
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,例如1<2;当左边操作数大于右边时,返回值为0,例如'good'<'god'('good'第3个位置的'o'字符在字母表中的顺序大于'god'中第3个位置的'd'字符,因此返回值为0);同样比较NULL值时返回NULL。
3.3.6、大于等于运算符(>=)
'>='运算符用来判断左边的操作数是否大于等于右边的操作数:如果大于等于,返回值为1;否则返回值为0。'>='不能用于判断空值NULL。
使用'>='进行比较判断,SQL语句如下:
sql
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,例如4>=4;当左边操作数小于右边时,返回值为0,例如1>=2;同样比较NULL值时返回NULL。
3.3.7、大于运算符(>)
'>'运算符用来判断左边的操作数是否大于右边的操作数:如果大于,返回值为1;否则返回值为0。'>'不能用于判断空值NULL。
使用'>'进行比较判断,SQL语句如下:
sql
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,例如5.5>5;左边操作数小于右边时,返回0,例如1>2;同样比较NULL值时返回NULL。
3.3.8、IS NULL(ISNULL)和IS NOT NULL运算符
IS NULL和ISNULL检验一个值是否为NULL:如果为NULL,返回值为1;否则返回值为0。IS NOT NULL检验一个值是否为非NULL:如果是非NULL,返回值为1;否则返回值为0。
使用IS NULL、ISNULL和IS NOTNULL判断NULL值和非NULL值,SQL语句如下:
sql
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 |
+--------------+--------------+------------+----------------+
由结果可以看到,IS NULL和ISNULL的作用相同,只是格式不同。ISNULL和IS NOTNULL的返回值正好相反。
3.3.9、BETWEEN AND运算符
语法格式为:
sql
expr BETWEEN min AND max
假如expr大于等于min且小于等于max,则BETWEEN的返回值为1,否则返回值为0。
使用BETWEEN AND进行值区间判断,输入SQL语句如下:
sql
select 4 between 2 and 5, 4 between 4 and 6, 12 between 9 and 10;
+-------------------+-------------------+---------------------+
| 4 between 2 and 5 | 4 between 4 and 6 | 12 between 9 and 10 |
+-------------------+-------------------+---------------------+
| 1 | 1 | 0 |
+-------------------+-------------------+---------------------+
select 'x' between 'f' and 'g', 'b' between 'a' and 'c';
+-------------------------+-------------------------+
| 'x' between 'f' and 'g' | 'b' between 'a' and 'c' |
+-------------------------+-------------------------+
| 0 | 1 |
+-------------------------+-------------------------+
由结果可以看到,4在端点值区间内或者等于其中一个端点值时,BETWEEN AND表达式返回值为1;12并不在指定区间内,因此返回值为0;对于字符串类型的比较,按字母表中字母顺序进行比较,'x'不在指定的字母区间内,因此返回值为0,而'b'位于指定字母区间内,因此返回值为1。
3.3.10、LEAST运算符
语法格式为:
sql
LEAST(值1,值2,...,值n)
其中,"值n"表示参数列表中有n个值。在有两个或多个参数的情况下,返回最小值。假如任意一个自变量为NULL,则LEAST()的返回值为NULL。
使用LEAST运算符进行大小判断,SQL语句如下:
sql
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> |
+-------------+-------------------------+----------------------+-----------------+
由结果可以看到,当参数是整数或者浮点数时,LEAST将返回其中最小的值;当参数为字符串时,返回字母表中顺序最靠前的字符;当比较值列表中有NULL时,不能判断大小,返回值为NULL。
3.3.11、GREATEST (value1,value2,...)
语法格式为:
sql
GREATEST(值1,值2,...,值n)
其中,n表示参数列表中有n个值。当有两个或多个参数时,返回值为最大值。假如任意一个自变量为NULL,则GREATEST()的返回值为NULL。
使用GREATEST运算符进行大小判断,SQL语句如下:
sql
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> |
+---------------+----------------------------+-------------------------+--------------------+
由结果可以看到,当参数中是整数或者浮点数时,GREATEST将返回其中最大的值;当参数为字符串时,返回字母表中顺序最靠后的字符;当比较值列表中有NULL时,不能判断大小,返回值为NULL。
3.3.12、IN、NOT IN运算符
IN运算符用来判断操作数是否为IN列表中的其中一个值:如果是,返回值为1;否则返回值为0。
NOT IN运算符用来判断表达式是否为IN列表中的其中一个值:如果不是,返回值为1;否则返回值为0。
使用IN、NOT IN运算符进行判断,SQL语句如下:
sql
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 |
+---------------------+--------------------------+
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 |
+-------------------------+------------------------------+
由结果可以看到,IN和NOT IN的返回值正好相反。
在左侧表达式为NULL的情况下,或是表中找不到匹配项并且表中一个表达式为NULL的情况下,IN的返回值均为NULL。
存在NULL值时的IN查询,SQL语句如下:
sql
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> |
+------------------------+-------------------------+
IN()语法也可用于在SELECT语句中进行嵌套子查询。
3.3.13、LIKE
LIKE运算符用来匹配字符串,语法格式为:
sql
expr LIKE匹配条件
- 如果expr满足匹配条件,则返回值为1(TRUE);
- 如果不匹配,则返回值为0(FALSE)。
expr或匹配条件中任何一个为NULL,则结果为NULL。
LIKE运算符在进行匹配时,可以使用下面的两种通配符:
'%',匹配任何数目的字符,甚至包括零字符。'_',只能匹配一个字符。
使用运算符LIKE进行字符串匹配运算,SQL语句如下:
sql
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> |
+--------------------+--------------------+------------------+--------------------+---------------+
由结果可以看到,指定匹配字符串为"stud"。"stud"表示直接匹配"stud"字符串,满足匹配条件,返回1;"stu_"表示匹配以stu开头的长度为4个字符的字符串,"stud"正好是4个字符,满足匹配条件,因此匹配成功,返回1;"%d"表示匹配以字母"d"结尾的字符串,"stud"满足匹配条件,匹配成功,返回1;"t _ _ _"表示匹配以't'开头的长度为4个字符的字符串,"stud"不满足匹配条件,因此返回0;当字符's'与NULL匹配时,结果为NULL。
3.3.14、REGEXP
REGEXP运算符用来匹配字符串,语法格式为:
sql
expr REGEXP匹配条件
- 如果expr满足匹配条件,返回1;
- 如果不满足,则返回0。
若expr或匹配条件任意一个为NULL,则结果为NULL。
REGEXP运算符在进行匹配时,常用的有下面几种通配符:
'^'匹配以该字符后面的字符开头的字符串。'$'匹配以该字符后面的字符结尾的字符串。'.'匹配任何一个单字符。"[...]"匹配在方括号内的任何字符。例如,"abc"匹配"a""b"或"c"。为了命名字符的范围,使用一个'-'。"a-z"匹配任何字母,而"0-9"匹配任何数字。'*'匹配零个或多个在它前面的字符。例如,"x*"匹配任何数量的'x'字符,"0-9"匹配任何数量的数字,而""匹配任何数量的任何字符。
使用运算符REGEXP进行字符串匹配运算,SQL语句如下:
sql
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 |
+--------------------+--------------------+----------------------+----------------------+
由结果可以看到,指定匹配字符串为"ssky"。"^s"表示匹配任何以字母's'开头的字符串,因此满足匹配条件,返回1;"y$"表示任何以字母"y"结尾的字符串,因此满足匹配条件,返回1;".sky"匹配任何以"sky"结尾、字符长度为4的字符串,满足匹配条件,返回1;"ab"匹配任何包含字母'a'或者'b'的字符串,指定字符串中既没有字母'a'也没有字母'b',因此不满足匹配条件,返回0。
3.4、逻辑运算符
在SQL中,所有逻辑运算符的求值所得结果均为TRUE、FALSE或NULL。在MySQL中,它们体现为1(TRUE)、0(FALSE)和NULL。逻辑运算符大多数都与不同的数据库SQL通用。
MySQL中的逻辑运算符如表所示。

3.4.1、NOT或者!
逻辑非运算符NOT或者!表示当操作数为0时,所得值为1;当操作数为非零值时,所得值为0;当操作数为NULL时,所得的返回值为NULL。
分别使用非运算符"NOT"和"!"进行逻辑判断,SQL语句如下:
sql
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 |
+--------+-----------+--------+----------+---------+
select !10, !(1-1), !-5, ! null, ! 1+1;
+-----+--------+-----+--------+-------+
| !10 | !(1-1) | !-5 | ! null | ! 1+1 |
+-----+--------+-----+--------+-------+
| 0 | 1 | 0 | <null> | 1 |
+-----+--------+-----+--------+-------+
select ! 1+1;
+-------+
| ! 1+1 |
+-------+
| 1 |
+-------+
由结果可以看到,前4列"NOT"和"!"的返回值都相同。为什么最后1列会出现不同的值呢?这是因为"NOT"与"!"的优先级不同。"NOT"的优先级低于"+",因此"NOT1+1"相当于"NOT(1+1)",先计算"1+1",然后再进行NOT运算,因为操作数不为0,因此NOT 1+1的结果是0;相反,"!"的优先级要高于"+"运算,因此"! 1+1"相当于"(!1)+1",先计算"!1",结果为0,再加1,最后结果为1。
3.4.2、AND或者&&
逻辑与运算符AND或者&&表示当所有操作数均为非零值并且不为NULL时,计算所得结果为1;当一个或多个操作数为0时,所得结果为0;其余情况返回值为NULL。
分别使用与运算符"AND"和"&&"进行逻辑判断,SQL语句如下:
sql
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 |
+----------+---------+------------+------------+
select 1 && -1, 1 && 0, 1 && null, 0 && null;
+---------+--------+-----------+-----------+
| 1 && -1 | 1 && 0 | 1 && null | 0 && null |
+---------+--------+-----------+-----------+
| 1 | 0 | <null> | 0 |
+---------+--------+-----------+-----------+
由结果可以看到,"AND"和"&&"的作用相同。"1 AND -1"中没有0或者NULL,因此结果为1;"1 AND 0"中有操作数0,因此结果为0;"1 AND NULL"中虽然有NULL,但是没有操作数0,返回结果为NULL。
"AND"运算符可以有多个操作数,需要注意的是:多个操作数运算时,AND两边一定要使用空格隔开,不然会影响结果的正确性。
3.4.3、OR或者||
逻辑或运算符OR或者||表示当两个操作数均为非NULL值且任意一个操作数为非零值时,结果为1,否则结果为0;当有一个操作数为NULL,且另一个操作数为非零值时,则结果为1,否则结果为NULL;当两个操作数均为NULL时,则所得结果为NULL。
分别使用或运算符"OR"和"||"进行逻辑判断,SQL语句如下:
sql
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> |
+--------------+--------+-----------+-----------+--------------+
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> |
+--------------+--------+----------+-----------+--------------+
由结果可以看到,"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 ORNULL"中只有NULL,返回结果为NULL。
3.4.4、XOR
逻辑异或运算符XOR表示当任意一个操作数为NULL时,返回值为NULL;对于非NULL的操作数,如果两个操作数都是非0值或者都是0值,则返回结果为0;如果一个为0值、另一个为非0值,返回结果为1。
使用异或运算符"XOR"进行逻辑判断,SQL语句如下:
sql
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 XOR 1"和"0 XOR 0"中,运算符两边的操作数都为非零值或者都是零值,因此返回0;在"1 XOR 0"中,两边的操作数一个为0值、一个为非0值,返回结果为1;在"1 XOR NULL"中,有一个操作数为NULL,返回结果为NULL;在"1 XOR 1XOR 1"中,有多个操作数,运算符相同,因此运算顺序从左到右依次计算,"1 XOR 1"的结果为0,再与1进行异或运算,最终结果为1。
a XOR b的计算等同于(a AND (NOT b))或者((NOT a)AND b)。
3.5、位运算符
位运算符是在二进制数上进行计算的运算符。位运算符会先将操作数变成二进制数,然后进行位运算,最后将计算结果从二进制变回十进制数。MySQL中提供的位运算符有按位或(|)、按位与(&)、按位异或(^)、按位左移(<<)、按位右移(>>)和按位取反(~),如表所示。

3.5.1、位或运算符(|)
位或运算的实质是将参与运算的几个数据按照对应的二进制数逐位进行逻辑或运算。对应的二进制位有一个或两个为1则该位的运算结果为1,否则为0。
使用位或运算符进行运算,SQL语句如下:
sql
select 10 | 15, 9 | 4 | 2;
+---------+-----------+
| 10 | 15 | 9 | 4 | 2 |
+---------+-----------+
| 15 | 15 |
+---------+-----------+
10的二进制数值为1010,15的二进制数值为1111,按位或运算之后,结果为1111,即整数15;9的二进制数值为1001,4的二进制数值为0100,2的二进制数值为0010,按位或运算之后,结果为1111,即整数15。其结果为一个64位无符号整数。
3.5.2、位与运算符(&)
位与运算的实质是将参与运算的几个操作数按照对应的二进制数逐位进行逻辑与运算。对应的二进制位都为1则该位的运算结果为1,否则为0。
使用位与运算符进行运算,SQL语句如下:
sql
select 10 & 15, 9 & 4 & 2;
+---------+-----------+
| 10 & 15 | 9 & 4 & 2 |
+---------+-----------+
| 10 | 0 |
+---------+-----------+
10的二进制数值为1010,15的二进制数值为1111,按位与运算之后,结果为1010,即整数10;9的二进制数值为1001,4的二进制数值为0100,2的二进制数值为0010,按位与运算之后,结果为0000,即整数0。其结果为一个64位无符号整数。
3.5.3、位异或运算符(^)
位异或运算的实质是将参与运算的两个数据按照对应的二进制数逐位进行逻辑异或运算。对应位的二进制数不同时,对应位的结果才为1。如果两个对应位数都为0或者都为1,则对应位的结果为0。
使用位异或运算符进行运算,SQL语句如下:
sql
select 10 ^ 15, 1 ^ 0, 1 ^ 1;
+---------+-------+-------+
| 10 ^ 15 | 1 ^ 0 | 1 ^ 1 |
+---------+-------+-------+
| 5 | 1 | 0 |
+---------+-------+-------+
10的二进制数值为1010,15的二进制数值为1111,按位异或运算之后,结果为0101,即整数5;1的二进制数值为0001,0的二进制数值为0000,按位异或运算之后,结果为0001;1和1本身二进制位完全相同,因此结果为0。
3.5.4、位左移运算符(<<)
位左移运算符<<使指定的二进制值的所有位都左移指定的位数。左移指定位数之后,左边高位的数值将被移出并丢弃,右边低位空出的位置用0补齐。语法格式为:expr<<n。其中,n指定值expr要移位的位数。
使用位左移运算符进行运算,SQL语句如下:
sql
select 1 << 2, 4 << 2;
+--------+--------+
| 1 << 2 | 4 << 2 |
+--------+--------+
| 4 | 16 |
+--------+--------+
1的二进制值为0000 0001,左移两位之后变成0000 0100,即十进制整数4;十进制4左移两位之后变成0001 0000,即变成十进制的16。
3.5.5、位右移运算符(>>)
位右移运算符>>使指定的二进制值的所有位都右移指定的位数。右移指定位数之后,右边低位的数值将被移出并丢弃,左边高位空出的位置用0补齐。语法格式为:expr>>n。其中,n指定值expr要移位的位数。
使用位右移运算符进行运算,SQL语句如下:
sql
select 1 >> 1, 16 >> 2;
+--------+---------+
| 1 >> 1 | 16 >> 2 |
+--------+---------+
| 0 | 4 |
+--------+---------+
1的二进制值为0000 0001,右移1位之后变成0000 0000,即十进制整数0;16的二进制值为0001 0000右移两位之后变成00000100,即变成十进制的4。
3.5.6、位取反运算符(~)
位取反运算的实质是将参与运算的数据按照对应的二进制数逐位反转,即1取反后变为0、0取反后变为1。
使用位取反运算符进行运算,SQL语句如下:
sql
select 5 & ~1;
+--------+
| 5 & ~1 |
+--------+
| 4 |
+--------+
在逻辑运算5&1中,由于位取反运算符''的级别高于位与运算符'&',因此先对1进行取反操作,取反之后,除了最低位为0外其他位都为1,即1110,然后与十进制数值5进行与运算,结果为0100,即整数4。
MySQL经过位运算之后的数值是一个64位的无符号整数,1的二进制数值表示为最右边位为1、其他位均为0,取反操作之后,除了最低位为0外,其他位均变为1。
3.6、运算符的优先级
运算符的优先级决定了不同的运算符在表达式中计算的先后顺序。下表列出了MySQL中的各类运算符及其优先级。

可以看到,不同运算符的优先级是不同的。一般情况下,级别高的运算符先进行计算,如果级别相同,MySQL按表达式的顺序从左到右依次计算。当然,在无法确定优先级的情况下,可以使用圆括号()来改变优先级,并且这样会使计算过程更加清晰。
4、综合案例------运算符的使用
1. 创建表tmp15,SQL语句如下:
sql
CREATE TABLE tmp15 (note VARCHAR(100), price INT);
2. 向表中插入一条记录,note值为"Thisisgood",price值为50,SQL语句如下:
sql
INSERT INTO tmp15 VALUES("Thisisgood", 50);
3. 对表tmp15中的整型数值字段price进行算术运算,执行过程如下:
sql
select price, price + 10, price - 10, price * 2, price / 2, price % 3
from tmp15;
+-------+------------+------------+-----------+-----------+-----------+
| price | price + 10 | price - 10 | price * 2 | price / 2 | price % 3 |
+-------+------------+------------+-----------+-----------+-----------+
| 50 | 60 | 40 | 100 | 25.0000 | 2 |
+-------+------------+------------+-----------+-----------+-----------+
4. 对表tmp15中的整型数值字段price进行比较运算,执行过程如下:
sql
select price, price > 10, price < 10, price != 10, price = 10, price <=> 10, price <> 10
from tmp15;
+-------+------------+------------+-------------+------------+--------------+-------------+
| price | price > 10 | price < 10 | price != 10 | price = 10 | price <=> 10 | price <> 10 |
+-------+------------+------------+-------------+------------+--------------+-------------+
| 50 | 1 | 0 | 1 | 0 | 0 | 1 |
+-------+------------+------------+-------------+------------+--------------+-------------+
5. 判断price值是否落在30~80区间,返回与70和30相比最大的值,判断price是否为IN列表(10, 20, 50, 35)中的某个值,执行过程如下:
sql
select price, price between 30 and 80, greatest(price, 70, 30), price in (10, 20, 50, 35)
from tmp15;
+-------+-------------------------+-------------------------+---------------------------+
| price | price between 30 and 80 | greatest(price, 70, 30) | price in (10, 20, 50, 35) |
+-------+-------------------------+-------------------------+---------------------------+
| 50 | 1 | 70 | 1 |
+-------+-------------------------+-------------------------+---------------------------+
6. 对tmp15中的字符串数值字段note进行比较运算,判断表tmp15中note字段是否为空;使用LIKE判断是否以字母't'开头;使用REGEXP判断是否以字母'y'结尾;判断是否包含字母'g'或者'm',执行过程如下:
sql
select note, note is null, note like 't%', note regexp '$y', note regexp '[gm]'
from tmp15;
+------------+--------------+----------------+------------------+--------------------+
| note | note is null | note like 't%' | note regexp '$y' | note regexp '[gm]' |
+------------+--------------+----------------+------------------+--------------------+
| Thisisgood | 0 | 1 | 0 | 1 |
+------------+--------------+----------------+------------------+--------------------+
7. 将price字段值与NULL、0进行逻辑运算,执行过程如下:
sql
select price, price && 1, price && null, price || 0, price and 0, 0 and null, price or null
from tmp15;
+-------+------------+---------------+------------+-------------+------------+---------------+
| price | price && 1 | price && null | price || 0 | price and 0 | 0 and null | price or null |
+-------+------------+---------------+------------+-------------+------------+---------------+
| 50 | 1 | <null> | 1 | 0 | 0 | 1 |
+-------+------------+---------------+------------+-------------+------------+---------------+
select price, !price, not null, price xor 3, 0 xor null, price xor 0
from tmp15;
+-------+--------+----------+-------------+------------+-------------+
| price | !price | not null | price xor 3 | 0 xor null | price xor 0 |
+-------+--------+----------+-------------+------------+-------------+
| 50 | 0 | <null> | 0 | <null> | 1 |
+-------+--------+----------+-------------+------------+-------------+
8. 将price字段值与2、4进行按位与、按位或操作,并对price字段进行按位取反,执行过程如下:
sql
select price, price & 2, price | 4, ~price
from tmp15;
+-------+-----------+-----------+----------------------+
| price | price & 2 | price | 4 | ~price |
+-------+-----------+-----------+----------------------+
| 50 | 2 | 54 | 18446744073709551565 |
+-------+-----------+-----------+----------------------+
9. 将price字段值分别左移和右移两位,执行过程如下:
sql
select price, price << 2, price >> 2
from tmp15;
+-------+------------+------------+
| price | price << 2 | price >> 2 |
+-------+------------+------------+
| 50 | 200 | 12 |
+-------+------------+------------+
5、常见问题
5.1、在MySQL中如何使用特殊字符?
单引号(')、双引号(")、反斜线(\)等在MySQL中是不能直接输入使用的,否则会产生意料之外的结果。在MySQL中,这些特殊字符称为转义字符,在输入时需要以反斜线符号('\')开头,所以在使用单引号和双引号时应分别输入(')或者("),输入反斜线时应该输入(\),其他特殊字符还有回车符(\r)、换行符(\n)、制表符(\tab)、退格符(\b)等。在向数据库中插入这些特殊字符时,一定要进行转义处理。
5.2、在MySQL中可以存储文件吗?
MySQL中的BLOB和TEXT字段类型可以存储数据量较大的文件,比如存储图像、声音或者是大容量的文本内容(例如网页或者文档)。虽然使用BLOB或者TEXT可以存储大容量的数据,但是对这些字段的处理会降低数据库的性能。如果并非必要,可以选择只存储文件路径。
5.3、在MySQL中如何执行区分大小写的字符串比较?
在Windows平台下,MySQL是不区分大小写的,因此字符串比较函数也不区分大小写。如果想执行区分大小写的比较,可以在字符串前面添加BINARY关键字。例如,默认情况下,'a'= 'A'的返回结果为1,如果使用BINARY关键字,即BINARY'a'='A',则结果为0。在区分大小写的情况下,'a'与'A'并不相同。