Mysql面试题之SQL语法篇

总结一些sql相关的易错知识点,大部分结论也适用于其他的数据库。

测试环境:Mysql 5.7

目录

测试数据

1、左上角的点(间隔号)表示对列名做标注,而普通的单引号则表示字符串

2、NULL和任何类型的数值做计算,结果都是null

3、不能对NULL使用比较运算符

4、null参与的逻辑运算,除了“真”、“假”两种结果外,可能还会出现另一种情况:“不确定”

5、聚合函数在运算时会忽略NULL值,但是COUNT除外

6、NULL在group by的时候,会被单独分在一组

7、NULL在order by时可能会被放到末尾,也可能会被放到开头,不参与排序

8、coalesce函数可以对NULL值做特殊处理

9、 NOT IN 语法对NULL无效

10、mysql中开始事务是 start transaction或者begin

11、mysql在排序字符型的列时,使用的是字典序('2'  >  10'')

12、DISTINCT也可以放在聚合函数里 count(DISTINCT 列名)

13、关联子查询的用法


​​​​​​​

测试数据

create table sale(
	id int primary key auto_increment,
	productName varchar(20),
	type varchar(10),
	price int,
	description varchar(200)
)

insert into sale(productName, type, price, description) values('苹果', '水果', 8, '不太好吃');
insert into sale(productName, type, price, description) values('外套', '衣服', 200, '很好看');
insert into sale(productName, type, price, description) values('短袖', '衣服', 120, null);
insert into sale(productName, type, price, description) values('电脑', '电子产品', 8000, '性能比较差');
insert into sale(productName, type, price, description) values('手机', '电子产品', 3000, null);
insert into sale(productName, type, price, description) values('橘子', '水果', 6, null);
insert into sale(productName, type, price, description) values('pad', '电子产品', 5000, null);
insert into sale(productName, type, price, description) values('菠萝', '水果', 20, '太酸了');
insert into sale(productName, type, price, description) values('羽绒服', '衣服', 800, null);
insert into sale(productName, type, price, description) values('西瓜', '水果', 18, null);

1、左上角的点(间隔号)表示对列名做标注,而普通的单引号则表示字符串

说明:左上角的点指的是和波浪号在一个格子的符号

验证:

间隔号

select `productName` from sale;

结果:

单引号

select 'productName' from sale;

结果:

2、NULL和任何类型的数值做计算,结果都是null

NULL在数据库中比较特殊,处理起来相对比较麻烦。

验证:

mysql> select null + 1;
+----------+
| null + 1 |
+----------+
| NULL     |
+----------+
1 row in set (0.02 sec)

mysql> select 1 + 1;
+-------+
| 1 + 1 |
+-------+
|     2 |
+-------+
1 row in set (0.03 sec)

3、不能对NULL使用比较运算符

对NULL进行比较运算是没有意义的。

验证:

mysql> select null < 1;
+----------+
| null < 1 |
+----------+
| NULL     |
+----------+
1 row in set (0.02 sec)

mysql> select 2 < 1;
+-------+
| 2 < 1 |
+-------+
|     0 |
+-------+
1 row in set (0.05 sec)

4、null参与的逻辑运算,除了“真”、“假”两种结果外,可能还会出现另一种情况:“不确定”

首先要明确以前,在mysql中,“真” 通常用1表示,“假” 用0表示,“不确定” 通常用null表示。

mysql> select true and null;
+---------------+
| true and null |
+---------------+
| NULL          |
+---------------+
1 row in set (0.01 sec)

mysql> select false and null;
+----------------+
| false and null |
+----------------+
|              0 |
+----------------+
1 row in set (0.01 sec)

可以看到,有null参与的运算,其结果需要格外注意。

两种运算的真值表如下:

AND运算

PQP  AND Q
不确定不确定
不确定
不确定不确定
不确定
不确定不确定不确定

OR运算

PQP OR Q
不确定
不确定不确定
不确定
不确定不确定
不确定不确定不确定

5、聚合函数在运算时会忽略NULL值,但是COUNT除外

要注意,只有count(*)是统计NULL的,如果是count(列名)同样也不会把NULL算在内。

把测试数据第一行的price改为null。

验证:

mysql> select sum(price) from sale;
+------------+
| sum(price) |
+------------+
| 17164      |
+------------+
1 row in set (0.02 sec)

mysql> select count(price) from sale;
+--------------+
| count(price) |
+--------------+
|            9 |
+--------------+
1 row in set (0.08 sec)

mysql> select count(*) from sale;
+----------+
| count(*) |
+----------+
|       10 |
+----------+
1 row in set (0.07 sec)

6、NULL在group by的时候,会被单独分在一组

验证:


mysql> select description, count(1) from sale group by description;
+-------------+----------+
| description | count(1) |
+-------------+----------+
| NULL        |        6 |
| 不太好吃    |        1 |
| 太酸了      |        1 |
| 很好看      |        1 |
| 性能比较差  |        1 |
+-------------+----------+
5 rows in set (0.04 sec)

7、NULL在order by时可能会被放到末尾,也可能会被放到开头,不参与排序

验证:

mysql> select * from sale order by price;
+----+-------------+----------+-------+-------------+
| id | productName | type     | price | description |
+----+-------------+----------+-------+-------------+
|  1 | 苹果        | 水果     | NULL  | 不太好吃    |
|  6 | 橘子        | 水果     |     6 | NULL        |
| 10 | 西瓜        | 水果     |    18 | NULL        |
|  8 | 菠萝        | 水果     |    20 | 太酸了      |
|  3 | 短袖        | 衣服     |   120 | NULL        |
|  2 | 外套        | 衣服     |   200 | 很好看      |
|  9 | 羽绒服      | 衣服     |   800 | NULL        |
|  5 | 手机        | 电子产品 |  3000 | NULL        |
|  7 | pad         | 电子产品 |  5000 | NULL        |
|  4 | 电脑        | 电子产品 |  8000 | 性能比较差  |
+----+-------------+----------+-------+-------------+
10 rows in set (0.06 sec)

8、coalesce函数可以对NULL值做特殊处理

通常用在select后面

coalesce(param1, param2, param3......)   参数的个数是可变得,返回第一个不为NULL的参数。

验证:


mysql> select productName, coalesce(description, '未知') from sale;
+-------------+-------------------------------+
| productName | coalesce(description, '未知') |
+-------------+-------------------------------+
| 苹果        | 不太好吃                      |
| 外套        | 很好看                        |
| 短袖        | 未知                          |
| 电脑        | 性能比较差                    |
| 手机        | 未知                          |
| 橘子        | 未知                          |
| pad         | 未知                          |
| 菠萝        | 太酸了                        |
| 羽绒服      | 未知                          |
| 西瓜        | 未知                          |
+-------------+-------------------------------+
10 rows in set (0.09 sec)

9、 NOT IN 语法对NULL无效

判断某个值是不是NULL,要用 IS NULL或者IS NOT NULL来判断。

所谓“无效”,指两方面

一是:结果集中不会出现NULL相关的列。

二是:in列表中如果出现为null的值,那么结果集肯定是空。 

验证

mysql> select productName, description from sale where description not in('太酸了');
+-------------+-------------+
| productName | description |
+-------------+-------------+
| 苹果        | 不太好吃    |
| 外套        | 很好看      |
| 电脑        | 性能比较差  |
+-------------+-------------+
3 rows in set (0.07 sec)

mysql> select productName, description from sale where description not in(null);
Empty set

mysql> select productName, description from sale where description not in('太酸了', null);
Empty set

10、mysql中开始事务是 start transaction或者begin

mysql中开始事务可以用下面两种方式

1、begin;

2、start transaction

不能用 begin transaction;

begin transaction:

start:

begin:

11、mysql在排序字符型的列时,使用的是字典序('2'  >  10'')

这一点在某些场合下,容易被误用,比如某个列都是数字,但是类型是varchar,如果把他当做数字来排序时,可能会出现意料之外的结果。

添加几条数据。

验证:

mysql> select * from sale order by description asc;
+----+-------------+----------+-------+-------------+
| id | productName | type     | price | description |
+----+-------------+----------+-------+-------------+
|  9 | 羽绒服      | 衣服     |   800 | NULL        |
| 10 | 西瓜        | 水果     |    18 | NULL        |
|  3 | 短袖        | 衣服     |   120 | 1           |
|  6 | 橘子        | 水果     |     6 | 10          |
|  5 | 手机        | 电子产品 |  3000 | 2           |
|  7 | pad         | 电子产品 |  5000 | 20          |
|  1 | 苹果        | 水果     | NULL  | 不太好吃    |
|  8 | 菠萝        | 水果     |    20 | 太酸了      |
|  2 | 外套        | 衣服     |   200 | 很好看      |
|  4 | 电脑        | 电子产品 |  8000 | 性能比较差  |
+----+-------------+----------+-------+-------------+

可以看到,升序时, “2”排在了“10”的后面,符合字典序,但不符合数字处理的逻辑。

所以说,如果确定某个列是数值型,那么在设计表的时候还是尽量不要用字符型。

12、DISTINCT也可以放在聚合函数里 count(DISTINCT 列名)

验证:

mysql> select count(type) from sale;
+-------------+
| count(type) |
+-------------+
|          10 |
+-------------+
1 row in set (0.06 sec)

mysql> select count( distinct type) from sale;
+-----------------------+
| count( distinct type) |
+-----------------------+
|                     3 |
+-----------------------+
1 row in set (0.07 sec)

小知识:mysql中distinct 是一个函数,但是有语法糖,可以不用加括号。

mysql> select distinct(type) from sale;
+----------+
| type     |
+----------+
| 水果     |
| 衣服     |
| 电子产品 |
+----------+
3 rows in set (0.06 sec)

mysql> select distinct type from sale;
+----------+
| type     |
+----------+
| 水果     |
| 衣服     |
| 电子产品 |
+----------+
3 rows in set (0.07 sec)

13、关联子查询的用法

有时候会遇到一些统计信息,出现“高于平均水平”或者“低于平均水平”等字样,就需要用到关联子查询。

比如我想查询出价格高于平均水平的商品以及他的数量,可以这么做

mysql> select productName, price from sale s1 where price > (select avg(price) from sale s2 where s1.type = s2.type group by s2.type);
+-------------+-------+
| productName | price |
+-------------+-------+
| 电脑        |  8000 |
| 菠萝        |    20 |
| 羽绒服      |   800 |
| 西瓜        |    18 |
+-------------+-------+
4 rows in set (0.02 sec)

参考《SQL 基础教程》,如有错误,欢迎指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值