MySQL例题一

多方面练习
1. 易错知识点

/* NULL和空值
-NULL也就是在字段中存储NULL值,空值也就是字段中存储空字符(’’)。

select length(NULL), length(''), length('1'),length('2');

+--------------+------------+-------------+-------------+
| length(NULL) | length('') | length('1') | length('2') |
+--------------+------------+-------------+-------------+
| NULL         |          0 |           1 |           1 |
+--------------+------------+-------------+-------------+
1 row in set

从上面看空值(’’)的长度是0,是不占用空间的;而NULL长度是NULL,其实它是占用空间的。
NULL列需要行中的额外空间来记录它们的值是否为NULL。

总结
1、空值不占空间,NULL值占空间。当字段不为NULL时,也可以插入空值。

2、当使用 IS NOT NULL 或者 IS NULL 时,只能查出字段中没有不为NULL的或者为 NULL 的,不能查出空值。

3、判断NULL 用IS NULL 或者 is not null,SQL 语句函数中可以使用IFNULL()函数来进行处理,判断空字符用 =’‘或者<>’'来进行处理。

4、在进行count()统计某列的记录数的时候,如果采用的NULL值,会别系统自动忽略掉,但是空值是会进行统计到其中的。

5、MySql中如果某一列中含有NULL,那么包含该列的索引就无效了。这一句不是很准确。

6:实际到底是使用NULL值还是空值(’’),根据实际业务来进行区分。个人建议在实际开发中如果没有特殊的业务场景,可以直接使用空值。



参考 NULL和空值
MySQL (37k) 关键字



*/

/*创建外键格式
CONSTRAINT fk_dept_personnel foreign key (d_id) references personnel(id)
CONSTRAINT 别名 foreign key (外键表值) references 主表(主表值)
*/
– COMMENT 创表时设置备注
– auto_increment 设置自增(整型)
– default 设置默认值
– IF EXISTS 判断是否存在(如果存在)

2. 基本创建练习题数据库语句

– 创建练习题数据库 字符集为utf8

create DATABASE Exercises_One CHARSET=utf8;

– 切换到Exercises_One下

use Exercises_One;

– 创建表之前先删除同名表(结构和数据)一般情况下同数据库下不能出现重名表

DROP TABLE IF EXISTS personnel;
create table personnel (
	id int(11) not null auto_increment COMMENT '主键id',
	name varchar(255) DEFAULT NULL COMMENT '名字 默认为空',
	age int(11) default null COMMENT '年龄 默认为空',
	salary int(10) default null COMMENT '工资 默认为空',
	leader int(11) default null COMMENT '领导 默认为空',
	menpai varchar(255) default null COMMENT '门派 默认为空',
primary key (id) COMMENT '主键'
)charset=utf8;
select * from personnel;

– 插入数据

INSERT INTO personnel VALUES(DEFAULT,'张丰',25,10000,0,'武当');
INSERT INTO personnel VALUES(DEFAULT,'张无忌',25,8000,0,'华山');
INSERT INTO personnel VALUES(DEFAULT,'岳不群',25,6500,0,'嵩山');
INSERT INTO personnel VALUES(DEFAULT,'东方不败',25,12000,0,'日月神教');
INSERT INTO personnel VALUES(DEFAULT,'令狐葱',25,4000,0,'武当');
INSERT INTO personnel VALUES(DEFAULT,'景天',25,2000,0,'华山');
INSERT INTO personnel VALUES(DEFAULT,'龙葵',25,10000,0,'嵩山');
INSERT INTO personnel VALUES(DEFAULT,'茂茂',25,10000,0,'日月神教');
INSERT INTO personnel VALUES(DEFAULT,'白豆腐',25,6500,0,'长白山');
INSERT INTO personnel VALUES(DEFAULT,'Farke',25,10000,0,'武当');
INSERT INTO personnel VALUES(DEFAULT,'Alex',25,10000,0,'Java');

– update set 根据id修改age

update personnel set age=27 WHERE id=2;
update personnel set age=28 WHERE id=3;
update personnel set age=23 WHERE id=4;
update personnel set age=29 WHERE id=5;
update personnel set age=30 WHERE id=6;
update personnel set age=28 WHERE id=7;
update personnel set age=28 WHERE id=8;
update personnel set age=26 WHERE id=9;
update personnel set age=23 WHERE id=10;

– 创建表之前先删除同名表(结构和数据)一般情况下同数据库下不能出现重名表

DROP TABLE IF EXISTS dept;
create table dept(
d_id int(11) not null auto_increment PRIMARY key COMMENT '主、外键',
d_name varchar(255) not null  COMMENT '部门名字',
adress VARCHAR(255) not null COMMENT '地址',
CONSTRAINT fk_dept_personnel foreign  key (d_id) references personnel(id)
)CHARACTER set=utf8;
select * from dept ;
select * from personnel;

– 插入数据

INSERT INTO dept VALUES(DEFAULT,'武当','河南');
INSERT INTO dept VALUES(DEFAULT,'华山','湖北');
INSERT INTO dept VALUES(DEFAULT,'嵩山','深圳');
INSERT INTO dept VALUES(DEFAULT,'日月神教','广州');
INSERT INTO dept VALUES(DEFAULT,'长白山','乌鲁木齐');
INSERT INTO dept VALUES(DEFAULT,'雇佣兵','新疆');

– 创建表之前先删除同名表(结构和数据)一般情况下同数据库下不能出现重名表

DROP TABLE IF EXISTS leaders;
create table leaders(
 l_id int(10) primary key  not null auto_increment COMMENT'主键',
 l_name varchar(255) default null COMMENT '名字 默认为空',
 CONSTRAINT fk_dleaderst_personnel foreign  key (l_id) references personnel(leader)
)CHARSET=utf8;

3. 测试例题

– 1.查询所有人员信息

select * from personnel;

– 2.只查询人员的姓名和年龄

select name,age from personnel;

– 3.查询年龄为28岁的有哪些人员

select * from personnel where age=28;

– 4.查询60岁以下的人员有哪些人员

select * from personnel where age<60;

– 5.查询27岁以上并且工资大于8000的人员有哪些

select * from personnel where age>27 and salary>8000;

– 6.查询姓[张]的人员有哪些
– 'like和 %'组合使用 模糊查询

select * from personnel where name LIKE'张%';

– 正则表达式 REGEXP

select * from personnel where name REGEXP '^张';

– 7.查询哪些人员属于 武当/华山/嵩山

select * from personnel where menpai in('武当','华山','嵩山');

select * from personnel where menpai=‘华山’;
select * from personnel where menpai=‘武当’;
select * from personnel where menpai=‘嵩山’;

– 8.查询工资在 5000-8900 的人员有哪些
– 逻辑运算符 <= >=

select * from personnel where 5000<=salary and salary>=8900;

– 9.查询所有人员,要求按工资倒序排列
– 倒叙order bay 正序desc

select * from personnel ORDER BY salary;
-- select * from personnel DESC salary;

– 10.查询令狐冲的领导人是谁
– 需要关联表,这里暂无信息

select * from personnel where id = (select leader from personnel where name = '令狐葱');

– 11.查询人员表中最高工资是多少
– MAX()最大值

select MAX(salary) from personnel;

– 12.查询人员表中最低工资是多少
– MIN()最小值

select  MIN(salary) FROM personnel;

– 13.查询所有人员的平均工资是多少
– AVG()平均数

select AVG(salary) from personnel;

– 14.查询所有人员的工资总和是多少
– SUM()总数

select SUM(salary) from personnel;

– 15.查询目前有多少个人员
– COUNT()统计总数

select COUNT(*) from personnel;
select COUNT(name) from personnel;
select COUNT(id) from personnel;

– 16.查询当前武林中有哪些门派
– DISTINCT 清除重复(去重)

select DISTINCT menpai from personnel ;

– GROUP BY 分组

select DISTINCT menpai from personnel GROUP BY  menpai;

– 17.查询 武当派 最高工资是谁

select  MAX(salary),NAME from personnel where menpai='武当';

– 18.查询各门派的平均工资是多少
– GROUP BY 分组查询
– ORDER BY排列

select  menpai,AVG(salary) from personnel GROUP  BY menpai;

– 19.查询当前武林中有哪些门派的平均工资大于8000 并按工资倒序排列
– HAVING
– DESC 倒序排列 组合 ORDER BY 使用
– HAVING 字句可以让我们筛选成组后的各种数据,where字句在聚合前先筛选记录,也就是说作用在group by和HAVING字句前。而 HAVING子句在聚合后对组记录进行筛选。我的理解就是真实表中没有此数据,这些数据是通过一些函数生存。

select menpai,AVG(salary)>8000 from personnel  GROUP BY menpai HAVING AVG(salary)>8000 ORDER BY AVG(salary) DESC;

– 20.查询当前人员表的中的第3条数据到第7条数据
– LIMIT 分页查询 可指定开始结束位置

select * from personnel LIMIT 2, 5;

– 21.查询哪些门派下没有弟子

select * from personnel GROUP BY menpai HAVING COUNT(*) =1;

select *from personnel GROUP BY menpai HAVING COUNT(*)=1;

– 22.查询武当派下有哪些弟子

select * from personnel where menpai='武当';

– 23.查询 各门派 的 工资总和 按倒序/正序排列
– 按什么什么排列 就要想起来分组和排序结合使用
– 正序 ASC

select menpai,SUM(salary) from personnel GROUP BY menpai ORDER BY SUM(salary) ASC;

– 倒叙 DESC

select menpai,SUM(salary) from personnel GROUP BY menpai ORDER BY SUM(salary) DESC;

– 24.删除工资重复的人员,请保留年龄最大的一个人
一般为逻辑删除,

DELETE FROM personnel where id in(
    SELECT id FROM (SELECT id from personnel where salary in(SELECT salary FROM personnel GROUP BY salary HAVING count(*)>1)
    AND age not in (SELECT MAX(age) FROM personnel GROUP BY salary HAVING count(*)>1)) as temp
);

– 25.将武当派 张三丰 修改为 张丰

update  set name='张三丰' where name='张丰';

select * from personnel;
select * from dept;

– 26.将所有门派大哥工资上调10%,但不包括Alex.
– != 非 不包含

update personnel set salary = salary+salary*0.1 where leader = 0 and name !='Alex';

– 27.查看哪些人员的门派已登记地理位置.
– 多表多列查询
– DISTINCT 清楚重复(去重)

select DISTINCT adress,d_name from personnel,dept where menpai=d_name;

– 28.查询所有人员门派的位置信息,不存在位置信息则不显示
– LEFT JOIN左连接 on后跟链接判断条件

select name,adress from personnel LEFT JOIN dept on menpai=d_name ;

– 29.在湖北省内的门派中的人员有哪些.

select name,adress from personnel LEFT JOIN dept on menpai=d_name where adress='湖北';

– 30.在陕西省内门派中的工资小于5000,年龄大于20岁的人员有哪些,按主键倒序排列

SELECT * FROM personnel INNER JOIN dept on personnel.menpai = dept.d_name
AND dept.adress = '湖北' and personnel.salary <5000 AND personnel.age >20 ORDER BY personnel.id DESC;