MySQL:数据类型和运算符

时间:2023-01-29 12:09:34
【例5.1】创建表tmp1,其中字段x、y、z、m、n数据类型依次为TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT,SQL语句如下:
CREATE TABLE tmp1 ( x TINYINT,  y SMALLINT,  z MEDIUMINT,  m INT,  n BIGINT );
执行成功之后,便用DESC查看表结构,结果如下:
DESC tmp1;
【例5.2】创建表tmp2,其中字段x、y、z数据类型依次为FLOAT(5,1)、DOUBLE(5,1)和DECIMAL(5,1),向表中插入数据5.12、5.15和5.123,SQL语句如下:
CREATE TABLE tmp2 ( x FLOAT(5,1),  y DOUBLE(5,1),  z DECIMAL(5,1) );
向表中插入数据:
INSERT INTO tmp2 VALUES(5.12, 5.15, 5.123);
Query OK, 1 row affected, 1 warning (0.00 sec)
可以看到在插入数据时,MySQL给出了一个警告信息,使用SHOW WARNINGS;语句查看警告信息:
SHOW WARNINGS;
+-------+------+-----------------------------------------------+
| Level | Code | Message                         |
+-------+------+-----------------------------------------------+
| Error  | 1265 | Data truncated for column 'z' at row 1 |
+-------+------+------------------------------------------------+
1 row in set (0.00 sec)
【例5.3】创建数据表tmp3,定义数据类型为YEAR的字段y,向表中插入值2010,’2010’,’2166’,SQL语句如下:
首先创建表tmp3:
CREATE TABLE tmp3(  y YEAR );
向表中插入数据:
INSERT INTO tmp3 values(2010),('2010');
再次向表中插入数据:
INSERT INTO tmp3 values ('2166');
ERROR 1264 (22003): Out of range value for column 'y' at row 1
语句执行之后,MySQL给出了一条错误提示,使用SHOW查看错误信息:
SHOW WARNINGS;
+---------+------+----------------------------------------------+
| Level   | Code | Message                       |
+---------+------+----------------------------------------------+
| Error | 1264 | Out of range value for column 'y' at row 1;
+---------+------+----------------------------------------------+
1 row in set (0.00 sec)
可以看到,插入的第3个值2166超过了YEAR类型的取值范围,此时不能正常的执行插入操作,查看结果:
SELECT * FROM tmp3;
+------+
| y    |
+------+
| 2010 |
| 2010 |
+------+
由结果可以看到,当插入值为数值类型的2010或者字符串类型的’2010’时,都正确的储存到了数据库中;而当插入值’2166’时,由于超出了YEAR类型的取值范围,因此,不能插入值。
【例5.4】向tmp3表中y字段插入2位字符串表示的YEAR值,分别为’0’、’00’、’77’和’10’,SQL语句如下:
首先删除表中的数据:
DELETE FROM tmp3;
向表中插入数据:
INSERT INTO tmp3 values('0'),('00'),('77'),('10');
查看结果:
SELECT * FROM tmp3;
+------+
| y    |
+------+
| 2000 |
| 2000 |
| 1977 |
| 2010 |
+------+
由结果可以看到,字符串’0’和’00’的作用相同,分别都转换成了2000年;’77’转换为1977;’10’转换为2010。
【例5.5】向tmp3表中y字段插入2位数字表示表示的YEAR值,分别为0、78和11,SQL语句如下:
首先删除表中的数据:
DELETE FROM tmp3;
向表中插入数据:
INSERT INTO tmp3 values(0),(78),(11);
查看结果:
SELECT * FROM tmp3;
+------+
| y    |
+------+
| 0000 |
| 1978 |
| 2011 |
+------+
由结果可以看到,0被转换为0000;78被转换为1978;11被转换为2011。
【例5.6】 创建数据表tmp4,定义数据类型为TIME的字段t,向表中插入值’10:05:05’,’23:23’,’2 10:10’,’3 02’,’10’,SQL语句如下:
首先创建表tmp4,
CREATE TABLE tmp4( t TIME );
向表中插入数据:
INSERT INTO tmp4 values('10:05:05 '), ('23:23'), ('2 10:10'), ('3 02'),('10');
查看结果:
SELECT * FROM tmp4;
+----------+
| t       |
+----------+
| 10:05:05 |
| 23:23:00 |
| 58:10:00 |
| 74:00:00 |
| 00:00:10 |
+----------+
由结果可以看到,’10:05:05’被转换为10:05:05;’23:23’被转换为23:23:00;’2 10:10’被转换为58:10:00,’3 02’被转换为74:00:00;’10’被转换成00:00:10。
在使用’D HH’格式时,小时一定要使用双位数值,如果是小于10的小时数,应在前面加0。
【例5.7】向表tmp4中插入值’101112’,111213,’0’,107010,SQL语句如下:
首先删除表中的数据:
DELETE FROM tmp4;
向表中插入数据:
INSERT INTO tmp4 values('101112'),(111213),( '0');
再向表中插入数据:
INSERT INTO tmp4 values ( 107010);
ERROR 1292 (22007): Incorrect time value: '107010' for column 't' at row 1
可以看到,在插入数据时,MySQL给出了一个错误提示信息,使用SHOW WARNINGS;查看错误信息,如下所示:
show warnings;
+---------+------+--------------------------------------------------+
| Level   | Code | Message                         |
+---------+------+--------------------------------------------------+
| Error | 1292 | Incorrect time value: '107010' for column 't' at row 1
+---------+------+---------------------------------------------------+
可以看到,第二次在插入记录的时候,数据超出了范围,原因是107010的分钟部分超过了60,分钟部分是不会超过60的,查看结果:
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字段列插入值。
【例5.8】向tmp4表中插入系统当前时间,SQL语句如下:
首先删除表中的数据:
DELETE FROM tmp4;
向表中插入数据:
INSERT INTO tmp4 values (CURRENT_TIME) ,(NOW());
查看结果:
SELECT * FROM tmp4;
+----------+
| t       |
+----------+
| 08:43:51 |
| 08:43:51 |
+----------+
由结果可以看到,获取系统当前的日期时间插入到TIME类型列,因为读者输入语句的时间不确定,因此获取的值与这里的可能是不同的,但都是系统当前的日期时间值。
【例5.9】创建数据表tmp5,定义数据类型为DATE的字段d,向表中插入“YYYY-MM-DD”和“YYYYMMDD”字符串格式日期,SQL语句如下:
首先创建表tmp5:
CREATE TABLE tmp5(d DATE);
Query OK, 0 rows affected (0.02 sec)
向表中插入“YYYY-MM-DD”和“YYYYMMDD”格式日期:
INSERT INTO tmp5 values('1998-08-08'),('19980808'),('20101010');
查看插入结果:
SELECT * FROM tmp5;
+------------+
| d        |
+------------+
| 1998-08-08 |
| 1998-08-08 |
| 2010-10-10 |
+------------+
可以看到,各个不同类型的日期值都正确的插入到了数据表中。
【例5.10】向tmp5表中插入“YY-MM-DD”和“YYMMDD”字符串格式日期,SQL语句如下:
首先删除表中的数据:
DELETE FROM tmp5;
向表中插入“YY-MM-DD”和“YYMMDD”格式日期:
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 |
+------------+
【例5.11】向tmp5表中插入YY-MM-DD和YYMMDD数字格式日期,SQL语句如下:
首先删除表中的数据:
DELETE FROM tmp5;
向表中插入YY-MM-DD和YYMMDD数字格式日期:
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 |
+------------+
【例5.12】向tmp5表中插入系统当前日期,SQL语句如下:
首先删除表中的数据:
DELETE FROM tmp5;
向表中插入系统当前日期:
INSERT INTO tmp5 values( CURRENT_DATE() ),( NOW() );
查看插入结果:
SELECT * FROM tmp5;
+-------------+
| d        |
+-------------+
| 2013-03-21 |
| 2013-03-21 |
+--------------+
CURRENT_DATE只返回当前日期值,不包括时间部分;NOW()函数返回日期和时间值,在保存到数据库时,只保留了其日期部分。
MySQL允许“不严格”语法:任何标点符号都可以用作日期部分之间的间隔符。例如,’98-11-31’、’98.11.31’、’98/11/31’和’98@11@31’是等价的,这些值也可以正确的插入到数据库。
【例5.13】创建数据表tmp6,定义数据类型为DATETIME的字段dt,向表中插入“YYYY-MM-DD HH:MM:SS”和“YYYYMMDDHHMMSS”字符串格式日期和时间值,SQL语句如下:
首先创建表tmp6:
CREATE TABLE tmp6(  dt DATETIME );
向表中插入“YYYY-MM-DD HH:MM:SS”和“YYYYMMDDHHMMSS”格式日期:
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 |
+-------------------------+
3 rows in set (0.00 sec)
可以看到,各个不同类型的日期值都正确的插入到了数据表中。
【例5.14】向tmp6表中插入“YY-MM-DD HH:MM:SS”和“YYMMDDHHMMSS”字符串格式日期和时间值,SQL语句如下:
首先删除表中的数据:
DELETE FROM tmp6;
向表中插入“YY-MM-DD HH:MM:SS”和“YYMMDDHHMMSS”格式日期:
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 |
+------------------------+
3 rows in set (0.00 sec)
【例5.15】向tmp6表中插入YYYYMMDDHHMMSS 和YYMMDDHHMMSS数字格式日期和时间值,SQL语句如下:
首先删除表中的数据:
DELETE FROM tmp6;
向表中插入YYYYMMDDHHMMSS和YYMMDDHHMMSS数字格式日期和时间:
INSERT INTO tmp6 values(19990909090909), (101010101010);
查看插入结果:
SELECT * FROM tmp6;
+--------------------------+
| dt                |
+-------------------------+
| 1999-09-09 09:09:09 |
| 2010-10-10 10:10:10 |
+-------------------------+
【例5.16】向tmp6表中插入系统当前日期和时间值,SQL语句如下:
首先删除表中的数据:
DELETE FROM tmp6;
向表中插入系统当前日期:
INSERT INTO tmp6 values( NOW() );
查看插入结果:
SELECT * FROM tmp6;
+-------------------------+
| dt                |
+-------------------------+
| 2013-03-21 20:28:06 |
+-------------------------+

【例 5.17】创建数据表tmp7,定义数据类型为TIMESTAMP的字段ts,向表中插入值’19950101010101’,’950505050505’,’1996-02-02 02:02:02’,’97@03@03 03@03@03’,121212121212,NOW(),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 |
| 2013-03-24 09:17:49 |
+-------------------------+
由结果可以看到,’19950101010101’被转换为1995-01-01 01:01:01;’950505050505’被转换为1995-05-05 05:05:05;’1996-02-02 02:02:02’被转换为1996-02-02 02:02:02;’97@03@03 03@03@03’被转换为1997-03-03 03:03:03;121212121212被转换为2012-12-12 12:12:12;NOW()被转换为系统当前日期时间2013-03-24 09:17:49。
TIMESTAMP与DATETIME除了存储字节和支持的范围不同外,还有一个最大的区别就是:DATETIME在存储日期数据时,按实际输入的格式存储,即输入什么就存储什么,与时区无关;而TIMESTAMP值的存储是以UTC(世界标准时间)格式保存的,存储时对当前时区进行转换,检索时再转换回当前时区。即查询时,根据当前时区的不同,显示的时间值是不同的。
【例5.18】向tmp7表中插入当前日期,查看插入值,更改时区为东10区,再次查看插入值,SQL语句如下:
首先删除表中的数据:
DELETE FROM tmp7;
向表中插入系统当前日期:
INSERT INTO tmp7 values( NOW() );
查看当前时区下日期值:
SELECT * FROM tmp7;
+-------------------------+
| ts                |
+-------------------------+
| 2013-03-24 10:02:42 |
+-------------------------+
查询结果为插入时的日期值,读者所在时区一般为东8区,下面修改当前时区为东10区,SQL语句如下:
set time_zone='+10:00';
再次查看插入时的日期值:
SELECT * FROM tmp7;
+-------------------------+
| ts                |
+-------------------------+
| 2013-03-24 12:02:42 |
+-------------------------+

【例5.19】下面将不同字符串保存到CHAR(4)和VARCHAR(4)列,说明CHAR和VARCHAR之间的差别,如表5.6所示。
表5.6  CHAR(4)与VARCHAR(4)存储区别
插入值    CHAR(4)    存储需求    VARCHAR(4)    存储需求
‘’    ‘    ’    4字节    ‘’    1字节
‘ab’    ‘ab  ’    4字节    ‘ab’    3字节
‘abc’    ‘abc’    4字节    ‘abc’    4字节
‘abcd’    ‘abcd’    4字节    ‘abcd’    5字节
‘abcdef’    ‘abcd’    4字节    ‘abcd’    5字节
对比结果可以看到,CHAR(4) 定义了固定长度为4的列,不管存入的数据长度为多少,所占用的空间均为4个字节。VARCHAR(4) 定义的列所占的字节数为实际长度加1。
当查询时CHAR(4) 和VARCHAR(4) 的值并不一定相同,如【例5.20】所示。
【例5.20】创建tmp8表,定义字段ch和vch数据类型依次为CHAR(4)、VARCHAR(4)向表中插入数据“ab  ”,SQL语句如下:
创建表tmp8:
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  )         |
+----------------------+---------------------+
1 row in set (0.00 sec)
从查询结果可以看到,ch在保存“ab  ”时将末尾的两个空格删除了,而vch字段保留了末尾的两个空格。

【例5.21】创建表tmp9,定义ENUM类型的列enm('first','second','third'),查看列成员的索引值,SQL语句如下:
首先,创建tmp9表:
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 |
|  second  |     2 |
|   third  |      3 |
| NULL   |  NULL |
+------------+----------+
可以看到,这里的索引值和前面所述的相同。
ENUM列总有一个默认值。如果将ENUM列声明为NULL,NULL值则为该列的一个有效值,并且默认值为NULL。如果ENUM列被声明为NOT NULL,其默认值为允许的值列表的第1个元素。
【例5.22】创建表tmp10,定义INT类型的soc字段,ENUM类型的字段level,列表值为('excellent','good', 'bad'),向表tmp10中插入数据’good’,1,2,3,’best’,SQL语句如下:
首先,创建数据表:
CREATE TABLE tmp10 (soc INT, level enum('excellent', 'good','bad') );
插入数据:
INSERT INTO tmp10 values(70,'good'), (90,1),(75,2),(50,3);
再次插入数据:
INSERT INTO tmp10 values (100,'best');
ERROR 1265 (01000): Data truncated for column 'level' at row 1
这里系统提示错误信息,可以看到,由于字符串值“best”不在ENUM列表中,所以对数据进行了阻止插入操作,查询结果如下:
SELECT * FROM tmp10;
+------+-----------+
| soc  | level    |
+------+-----------+
|   70 | good    |
|   90 | excellent |
|   75 | good    |
|   50 | bad     |
+------+-----------+
由结果可以看到,因为ENUM列表中的值在MySQL中都是以编号序列存储的,因此,插入列表中的值“good”或者插入其对应序号’2’的结果是相同的;“best”不是列表中的值,因此不能插入数据。

【例5.23】创建表tmp11,定义SET类型的字段s,取值列表为('a', 'b', 'c', 'd'),插入数据('a'),('a,b,a'),('c,a,d'),('a,x,b,y'),SQL语句如下:
首先创建表tmp11:
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');
ERROR 1265 (01000): Data truncated for column 's' at row 1
由于插入了SET列不支持的值,因此MySQL给出错误提示。
查看结果:
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”。

【例5.24】创建表tmp12,定义BIT(4)类型的字段b,向表中插入数据2、9、15、16。
首先创建表tmp12,SQL语句如下:
CREATE TABLE tmp12( b BIT(4) );
插入数据:
INSERT INTO tmp12 VALUES(2), (9), (15);
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings:1
查询插入结果:
SELECT BIN(b+0) FROM tmp12;
+------------+
| BIN(b+0) |
+------------+
| 10       |
| 1001     |
| 1111     |
+------------+
4 rows in set (0.00 sec)
b+0表示将二进制的结果转换为对应的数字的值,BIN() 函数将数字转换为二进制。从结果可以看到,成功的将3个数插入到表中。


【例5.25】创建表tmp13,定义BINARY(3)类型的字段b和VARBINARY(3)类型的字段vb,并向表中插入数据’5’,比较两个字段的存储空间。
首先创建表tmp13,输入SQL语句如下:
CREATE TABLE tmp13(
b binary(3),  vb varbinary(30)
);
插入数据:
INSERT INTO tmp13 VALUES(5,5);
查看两个字段存储数据的长度:
SELECT length(b), length(vb) FROM tmp13;
+-----------+---------------+
| length(b) | length(vb)  |
+-----------+---------------+
|       3 |         1 |
+-----------+---------------+
1 row in set (0.00 sec)
可以看到,b字段的值数据长度为3,而vb字段的数据长度仅为插入的一个字符的长度1。
如果想要进一步确认’5’在两个字段中不同的存储方式,输入如下语句:
SELECT b,vb,b = '5', b='5\0\0',vb='5',vb = '5\0\0' FROM tmp13;
+------+------+---------+-----------+--------+--------------+
| b    | vb   | b = '5' | b='5\0\0' | vb='5' | vb = '5\0\0' |
+------+------+---------+-----------+--------+--------------+
| 5    | 5    |    0 |       1 |    1 |         0 |
+------+------+---------+-----------+--------+--------------+
1 row in set (0.00 sec)
由执行结果可以看出,b字段和vb字段的长度是截然不同的,因为b字段不足的空间填充了’\0’,而vb字段则没有填充。

【例5.26】创建表tmp14,定义数据类型为INT的字段num,插入值64,对num值进行算术运算:
首先创建表tmp14,输入语句如下:
CREATE TABLE tmp14 ( num INT);
向字段num插入数据64:
INSERT INTO tmp14 value(64);
接下来,对num值进行加法和减法运算:
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进行乘法、除法运算。
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。
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.29】使用’=’进行相等判断,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 |
+-----+-------+-----+----------+---------+------------------+-------------------+
1 row in set (0.00 sec)

【例5.30】使用’<=>’进行相等的判断,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 |
+-------+------------+--------+--------------+----------+--------------------+----------------------+
1 row in set (0.00 sec)
由结果可以看到,’<=>’在执行比较操作时和’=’的作用是相似的,唯一的区别是’<=>’可以用来对NULL进行判断,两者都为NULL时返回值为1。
3.不等于运算符 <>或者 !=
‘<>’或者’!=’用于判断数字、字符串、表达式不相等的判断。如果不相等,返回值为1;否则返回值为0。这两个运算符不能用于判断空值NULL。
【例5.31】使用’<>’和’!=’进行不相等的判断,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 |
+---------------+-------+------+--------+---------------+----------------------+
1 row in set (0.00 sec)
由结果可以看到,两个不等于运算符作用相同,都可以进行数字、字符串、表达式的比较判断。

【例5.32】使用’<=’进行比较判断,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 row in set (0.00 sec)
由结果可以看到,左边操作数小于或者等于右边时,返回值为1,例如:4<=4;当左边操作数大于右边时,返回值为0,例如:’good’第3个位置的’o’字符在字母表中的顺序大于’god’中的第3个位置的’d’字符,因此返回值为0;同样比较NULL值时返回NULL。

【例5.33】使用’<’进行比较判断,SQL语句如下:
SELECT 'good'<'god', 1<2, 4<4, 5.5<5, (1+3) < (2+1),NULL<NULL;

【例5.34】使用’>=’进行比较判断,SQL语句如下:
SELECT 'good'>='god', 1>=2, 4>=4, 5.5>=5, (1+3) >= (2+1),NULL>=NULL;
【例5.35】使用’>’进行比较判断,SQL语句如下:
SELECT 'good'>'god', 1>2, 4>4, 5.5>5, (1+3) > (2+1),NULL>NULL;

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

【例5.37】使用BETWEEN AND 进行值区间判断,输入SQL语句如下:
SELECT 4 BETWEEN 4 AND 6, 4 BETWEEN 4 AND 6,12 BETWEEN 9 AND 10;

SELECT  'x' BETWEEN 'f' AND 'g', 'b' BETWEEN 'a' AND 'c';

【例5.38】使用LEAST运算符进行大小判断,SQL语句如下:
SELECT least(2,0), least(20.0,3.0,100.5), least('a','c','b'),least(10,NULL);

【例5.39】使用GREATEST运算符进行大小判断,SQL语句如下:
SELECT greatest(2,0), greatest(20.0,3.0,100.5), greatest('a','c','b'),greatest(10,NULL);

【例5.40】使用IN、NOT IN运算符进行判断,SQL语句如下:
SELECT 2 IN (1,3,5,'thks'), 'thks' IN (1,3,5,'thks');

【例5.41】存在NULL值时的IN查询,SQL语句如下:
SELECT NULL IN (1,3,5,'thks'),10 IN (1,3,NULL,'thks');

【例5.42】使用运算符LIKE进行字符串匹配运算,SQL语句如下:
SELECT 'stud' LIKE 'stud', 'stud' LIKE 'stu_','stud' LIKE '%d','stud' LIKE 't_ _ _', 's' LIKE NULL;

【例5.43】使用运算符REGEXP进行字符串匹配运算,SQL语句如下:
SELECT 'ssky' REGEXP '^s', 'ssky' REGEXP 'y$', 'ssky' REGEXP '.sky', 'ssky' REGEXP '[ab]';

【例5.44】分别使用非运算符“NOT”和“!”进行逻辑判断,SQL语句如下:
 SELECT NOT 10, NOT (1-1), NOT -5, NOT NULL, NOT 1 + 1;

 SELECT !10, !(1-1), !-5, ! NULL, ! 1 + 1;
【例5.45】分别使用与运算符“AND”和“&&”进行逻辑判断,SQL语句如下:
 SELECT  1 AND -1,1 AND 0,1 AND NULL, 0 AND NULL;

 SELECT  1 && -1,1 && 0,1 && NULL, 0 && NULL;

【例5.46】分别使用或运算符“OR”和“||”进行逻辑判断,SQL语句如下:
 SELECT  1 OR -1 OR 0, 1 OR 2,1 OR NULL, 0 OR NULL, NULL OR NULL;
 SELECT  1 || -1 || 0, 1 || 2,1 || NULL, 0 || NULL, NULL || NULL;
【例5.47】使用异或运算符“XOR”进行逻辑判断,SQL语句如下:
SELECT 1 XOR 1, 0 XOR 0, 1 XOR 0, 1 XOR NULL, 1 XOR 1 XOR 1;
执行上面的语句,结果如下。
 SELECT 1 XOR 1, 0 XOR 0, 1 XOR 0, 1 XOR NULL, 1 XOR 1 XOR 1;

【例5.48】使用位或运算符进行运算,SQL语句如下:
 SELECT 10 | 15, 9 | 4 | 2;

【例5.49】使用位与运算符进行运算,SQL语句如下:
 SELECT 10 & 15, 9 &4& 2;
【例5.50】使用位异或运算符进行运算,SQL语句如下:
 SELECT 10 ^ 15, 1 ^0, 1 ^ 1;
【例5.51】使用位左移运算符进行运算,SQL语句如下:
 SELECT 1<<2, 4<<2;
【例5.52】使用位右移运算符进行运算,SQL语句如下:
 SELECT 1>>1, 16>>2;
【例5.53】使用位取反运算符进行运算,SQL语句如下:
 SELECT 5 & ~1;



综合案例

1. 案例目的
创建数据表,并对表中的数据进行运算操作,掌握各种运算符的使用方法。
创建表tmp15,其中包含VARCHAR类型的字段note和INT类型的字段price,使用运算符对表tmp15中不同的字段进行运算;使用逻辑操作符对数据进行逻辑操作;使用位操作符对数据进行位操作。
本案例使用数据表tmp15,首先创建该表,SQL语句如下:
CREATE TABLE tmp15 (note VARCHAR(100), price INT);
向表中插入一条记录,note值为“Thisisgood”,price值为50,SQL语句如下:
INSERT INTO tmp15 VALUES(“Thisisgood”, 50);
2. 案例操作过程
  对表tmp15中的整型数值字段price进行算术运算,执行过程如下:
 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 |
+--------+------------+-----------+-----------+-----------+---------+
  对表tmp15中的整型数值字段price进行比较运算,执行过程如下:
 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 |
+------ -+-----------+-----------+--------------+------------+----------------+--------------+
判断price值是否落在30~80区间;返回与70,30相比最大的值,判断price是否为IN列表(10, 20, 50, 35)中的某个值,执行过程如下:
mysql> 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 |
+--------+------------------------------------+--------------------------------+----------------------------+
  对tmp15中的字符串数值字段note进行比较运算,判断表tmp15中note字段是否为空;使用LIKE判断是否以字母’t’开头;使用REGEXP判断是否以字母’y’结尾;判断是否包含字母’g’或者’m’,执行过程如下:
mysql> 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 |
+--------------+-----------------+------------------+----------------------+---------------------------+
  将price字段值与NULL,0进行逻辑运算,执行过程如下:
mysql> 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 |
+--------+--------------+-------------------+-----------+---------------+------------------+--------------------+
1 row in set (0.00 sec)

mysql>  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 |
+--------+--------+--------------+----------------+-----------------+-----------------+
1 row in set (0.00 sec)
  将price字段值与2、4进行按位与、按位或操作,并对price进行按位操作,执行过程如下:
mysql> SELECT price, price&2 , price|4, ~price FROM tmp15 ;
+--------+----------+---------+-----------------------------+
| price  | price&2 | price|4 | ~price               |
+--------+----------+---------+-----------------------------+
|    50 |      2 |    54 | 18446744073709551565 |
+--------+----------+---------+------------------------------+
  将price字段值分别左移和右移两位,执行过程如下:
mysql> SELECT price, price<<2, price>>2  FROM tmp15 ;
+--------+------------+-----------+
| price  | price <<2 | price>>2 |
+--------+------------+-----------+
|    50 |     200 |      12 |
+--------+------------+-----------+