MySQL DDL、DML、DQL语法及表关系、多表查询

MySQL DDL、DML、DQL语法及表关系、多表查询

  • 1.DDL:数据定义语言(Data Definition Language)
  • 2.DML:数据操作语言(Data Manipulation Lanuage)
  • 3.DQL:数据查询语言(Data Query Lanuage)
  • 4.DCL:数据控制语言(Data Control Language)
  • 5.SQL约束
  • 6.SQL视图
  • 7.SQL索引
  • 8.表与表之间的关系、多表查询
  • 9.MySql实战

首先登录数据库

-- 登录数据库
mysql -uroot –p 或 
mysql -h127.0.0.1 --user=root --password=root

1.DDL:数据定义语言(Data Definition Language)

关键字:(创建(create)一个结构,修改(alter)一个结构,删除(drop 摧毁)一个结构);用于对操作对象(数据库,表,视图等)做创建,修改,删除等操作

//一、DDL之数据库操作:database
	//1.创建数据库
	create database 数据库名;//默认编码 utf-8
	create database 数据库名 character set 字符集;//指定数据库的编码
	//2.查看数据库
	show databases;//查看服务器的所有数据库
	show create database 数据库名;//查看某个数据库的定义的信息
	//3.删除数据库
	drop database 数据库名称;
	//4.使用数据库
	select database();//查看正在使用的数据库
	use 数据库名;//使用某个数据库
//二、DDL之表操作:table
	//1.创建表
	//1.1地区表
	CREATE TABLE `area` (
	`a_id` int(8) NOT NULL auto_increment COMMENT '地区ID',
	`a_name` varchar(32) default NULL COMMENT '地区名称',
	PRIMARY KEY  (`a_id`)
	) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8
	
	//1.2学校表
	CREATE TABLE `school` (
	`sc_id` int(8) NOT NULL auto_increment COMMENT '学校表的主键ID',
	`sc_name` varchar(32) default NULL COMMENT '学校名称',
	`a_id` int(8) default NULL COMMENT '所属区域外键',
	PRIMARY KEY  (`sc_id`)
	) ENGINE=InnoDB AUTO_INCREMENT=158 DEFAULT CHARSET=utf8
 	
 	//1.3学生表
 	CREATE TABLE `student` (
 	`s_id` int(8) NOT NULL auto_increment COMMENT '学生编号',
 	`s_name` varchar(32) default NULL COMMENT '学生姓名',
 	`s_sex` int(1) default NULL COMMENT '性别 0(女) 1(男)',
 	`s_birthday` date default NULL,
 	`s_examnum` varchar(32) default NULL,
 	`sc_id` int(8) default NULL,
 	PRIMARY KEY  (`s_id`),
 	KEY `index_student_sname` (`s_name`)
 	) ENGINE=InnoDB AUTO_INCREMENT=39132 DEFAULT CHARSET=utf8
	
	//2.查看表
	show tables;//查看数据库中的所有表
	select * from 表名;//查询当前表中所有的数据
	desc 表名;//查看表结构
	
	//3.删除表
	drop table 表名;
	
	//3.修改表结构
	1.alter table 表名 add 列名 类型(长度) [约束];//新增字段
	2.alter table 表名 modify 列名 类型(长度) [约束];//修改字段的类型长度及约束
	3.alter table 表名 change 旧列名 新列名 类型(长度) [约束]//修改字段名称
	4.alter table 表名 drop 列名;//删除字段
	5.rename table 表名 to 新表名;//修改表名

2.DML:数据操作语言(Data Manipulation Lanuage)

关键字:insert(添加),delete(删除),update(修改)等
用于表中数据的增删改操作

//DML之数据操作语言
	//1.插入表数据:insert
		//A.向表中插入某些字段
		insert into(字段1,字段2,字段3,...) values (1,2,3,...);
		//B.向表中所有的字段设置值,要求:值的顺序与字段的顺序一致
		insert intovalues (1,2,3,...);
	//2.修改表数据:update
		//A.更新所有记录的指定字段
		update 表名 set 字段名=,字段名=,...;
		//B.更新符合条件记录的指定字段
		update 表名 set 字段名=,字段名=,... where 条件;
	//3.删除表数据:delete
		//A.如果删除表中的部分数据
		delete from 表名 where 条件;//是从表中把数据一条一条的删除
		//B.如果删除表中所有数据
		delete from 表名;//是从表中把数据一条一条的删除,所以这样删除大表数据的时候一条一条删会很慢
		truncate table 表名;//慎重使用:它不管表中有多少记录,它会先摧毁这个表结构,然后重建表结构,所以这样在删除大表数据的时候就会很快;

3.DQL:数据查询语言(Data Query Lanuage)

关键字:select,from,where等 查询(SELECT)
用于查询表中的数据

# 语法:select [distinct]  * | 列名,列名 from 表 where 条件;
	# 简单查询
		select * from 表名;  --查全表
		select 字段1,字段2,…… from 表名;  --按字段查找
		-- 别名查询.使用的关键字是as(as可以省略的)
		select 表别名.字段1,表别名.字段2,…… from 表名 表别名;  --表别名
		select 字段1 别名,字段2 别名,…… from 表名;  --列别名(1.更清楚的标记这一列是什么 2.简化列名)
		-- 去掉重复值
		select distinct 字段 from 表名;
		-- 查询结果是表达式(运算查询)
		select 名称,价格 旧,(价格+10)from 表名;
	# 条件查询
		-- 查询指定字段 = 指定值的所有信息
		SELECT * FROM 表名 WHERE 字段名 =;
		-- 查询指定字段 != 指定值的所有信息
		SELECT * FROM 表名 WHERE 字段名 !=;
		-- 查询指定字段 > 指定值的所有信息
		SELECT * FROM 表名 WHERE 字段名 >;
		-- 查询指定字段 在指定范围内 的所有信息
		SELECT * FROM product WHERE price >= 2000 AND price <=10000;  --标准写法
		SELECT * FROM product WHERE price BETWEEN 2000 AND 10000;  --简易写法 效果一样
		-- 查询指定字段<指定值 或 指定字段>指定值 的所有信息
		select * from 表名 where 字段名 >or 字段名 <;
		
		--MySQL的模糊查询,Like语句中,%代表零个或多个任意字符,_代表一个字符,列如LIKE '%某字%';
		-- 查询指定字段 含有某字的所有记录
		select * from 表名 where 字段名 LIKE '%某字%';
		-- 查询指定字段以'某字'开头的所有记录
		select * from 表名 where 字段名 LIKE '某字%';
		-- 查询指定字段 第二个字为'某字'的所有记录
		select * from 表名 where 字段名 LIKE '_某字%';
		-- 查询指定字段为空的记录
		select * from 表名 where 字段名 is null;
		-- 查询指定字段不为空的记录
		select * from 表名 where 字段名 is not null;
	# 排序查询
	语法:SELECT * FROM 表名 ORDER BY 排序字段 ASC(升序 默认)|DESC 降序;
		-- 按照指定字段(降序)排序
		SELECT * FROM 表名 ORDER BY 排序字段 DESC;
		-- 按照指定字段1(降序)排序的基础上,并按照指定字段2(降序)排序
		SELECT * FROM 表名 ORDER BY 排序字段1 DESC,排序字段2 DESC;
		-- 按照指定字段1去重基础上,按照指定字段2(降序)排序
		SELECT DISTINCT 去重字段 FROM 表名 ORDER BY 排序字段 DESC;
	# 聚合查询
		SELECT COUNT(*) FROM 表名;  --cout(*)包括了所有的列,相当于行数,在统计结果的时候,不会忽略NULL
		SELECT COUNT(字段) FROM 表名;  --count(列名)会统计该列字段在表中出现的次数,会忽略字段为null 的情况,即不统计字段为null 的记录 
		SELECT COUNT(1) FROM 表名;  --COUNT(1)会统计表中的所有的记录数,不会忽略NULL,包含字段为null 的记录
		-- 查询 指定字段>指定值 的总记录数
		SELECT COUNT(*) FROM 表名 WHERE 指定字段 > 指定值;
		-- 查询分类为 1 的所有商品的总和
		SELECT SUM(price) FROM product WHERE c_id = 1;
		-- 查询分类为2所有商品的平均价格
		SELECT AVG(price) FROM product WHERE c_id = 2;
		-- 查询商品的最大价格和最小价格
		SELECT MAX(price),MIN(price) FROM product;
	# 分组查询
	语法:SELECT 字段1,字段2FROM 表名GROUP BY分组字段 HAVING 分组条件;
	分组操作中的having子语句,是用于在分组后对数据进行过滤的,作用类似于where条件。
	havingwhere的区别:
	having是在分组后对数据进行过滤;where是在分组前对数据进行过滤
	having后面可以使用分组函数(统计函数)where后面不可以使用分组函数
		-- 1 统计各个分类商品的个数
		SELECT c_id ,COUNT(*) FROM product GROUP BY c_id;
		-- 2 统计各个分类商品的个数,且只显示个数大于3的信息
		SELECT c_id ,COUNT(*) FROM product GROUP BY c_id HAVING COUNT(*) > 3;

4.DCL:数据控制语言(Data Control Language)

与用户相关的操作,比如创建,删除,权限修改等
用来定义数据库的访问权限和安全级别,及创建用户。
因为工作中的权限问题,所以应用较少,这里不演示。

5.SQL约束

一、约束条件分类:
1not null :非空约束,保证字段的值不能为空
     s_name VARCHAR(10) NOT NULL, #非空

2default:默认约束,保证字段总会有值,即使没有插入值,都会有默认值!
     age INT DEFAULT 18, #默认约束

3unique:唯一,保证唯一性但是可以为空,比如座位号
     s_seat INT UNIQUE,#唯一约束

4check:检查性约束【MySQL不支持,语法不报错,但无效】
     s_sex CHAR(1) CHECK(s_sex='男' OR s_sex='女'),#检查约束(Mysql无效)

5primary key :主键约束唯一标识数据库表中的每条记录。同时保证唯一性和非空
     添加主键约束:创建表时,在该字段描述处,声明指定字段为主键:
     id INT PRIMARY KEY,#主建约束(唯一性,非空)
     
6auto_increment(关键字)自动增长列:自动增长列类型必须是整形,自动增长列必须为键(一般是主键)

7foreign key:外键约束,用于限制两个表的关系,保证从表该字段的值来自于主表相关联的字段的值!
     teacher_id INT REFERENCES teacher(id)   #这是外键,写在列级,Mysql无效

	为了表明商品属于哪个分类,通常情况下,我们将在商品表上添加一列,用于存放分类c_id的信息,此列称为:外键;
	此时“分类表category”称为:主表,“cid”我们称为主键。“商品表products”称为:从表,c_id称为外键。
	外键特点:从表外键的值是对主表主键的引用。从表外键类型,必须与主表主键类型一致。
	[外键名称] 用于删除外键约束的,一般建议“_fk”结尾
	使用外键目的:保证数据完整性
	# 声明外键约束的语法:
	alter table 从表 add [constraint] [外键名称] foreign key (从表外键字段名) references 主表 (主表的主键);
	# 删除外键约束的语法:
	alter table 从表 drop foreign key 外键名称
	
	##外键约束案例:
	--添加约束:
	alter table product add CONSTRAINT fk_product_cid FOREIGN key (c_id) REFERENCES category(cid);
	--验证约束:
	-- 1 向分类表中添加数据
	insert into category values (null,'家用电器/电脑');
	-- 2 向商品表中添加已经存在的商品类别的商品
	INSERT INTO product VALUES(null,' 联想(Lenovo)威6 14英寸商务轻薄笔记本电脑(i7-8550U 8G 256G PCIe SSD FHD MX150 Win10 两年上门)鲨鱼灰',5999,1);
	-- 3 向商品表中添加不存在的商品类别的商品 (报错,违反了主外键约束)
	INSERT INTO product VALUES(null,'七匹狼休闲裤男2018秋装新款纯棉男士直筒商务休闲长裤子男装 2775 黑色 32/80A',299,2);
	-- 4 删除指定分类(分类被商品使用) -- 执行异常(因为要删除的商品分类被外检表引用,所以会报错)
	delete from category where cid = 1;

6.SQL视图

# 视图
为什么需要视图?满足不同的人员关注不同的数据,同时保证信息的安全性
概念:视图是一张虚拟表,表示一张表的部分数据或多张表的综合数据,其结构和数据是建立在对表的查询基础上;视图中不存放数据,数据存放在视图所引用的原始表中。
用途:筛选表中的行、防止未经许可的用户访问敏感数据、降低数据库的复杂程度、将多个物理数据库抽象为一个逻辑数据库。
此处需要注意:视图是一个虚拟表,视图是不允许出现重复列的!而且封装视图的查询结果中也不能用用子查询!这两点一定要切记!
# 创建视图语法
create view 视图名称 as <select语句>;
# 删除视图语法
drop view [if exists] 视图名称;  //[if exists]删除前判断视图是否存在
# 查询视图语法
select * from 视图名称;

7.SQL索引

-- Mysql索引
索引技术就是为了让数据库 更快的定位一条数据所采用的一种查询性能优化技术。
索引是一种有效组	合数据的方式,为快速查找到指定记录。
作用:大大提高数据库的检索速度、改善数据库性能。
MySQL索引按存储类型分类B-树索引、哈希索引。
-- Mysql索引分类:
	普通索引:基本索引类型;允许在定义索引的列中插入重复值和空值
	唯一索引:索引列数据不重复;允许有空值
	主键索引:主键列中的每个值是非空、唯一的;一个主键将自动创建主键索引
	复合索引:将多个列组合作为索引
	全文索引:支持值的全文查找;允许重复值和空值
	空间索引:对空间数据类型的列建立的索引
-- MySql创建索引的语法
-- 普通索引
	-- 直接创建普通索引:
	CREATE INDEX indexName ON mytable(username(length)); 
	-- 修改表结构的方式添加普通索引
	ALTER table tableName ADD INDEX indexName(columnName);
	-- 创建表的时候同时创建普通索引
	CREATE TABLE `table` (字段1,字段2,……,INDEX [indexName] (username(length)));
-- 唯一索引
	-- 直接创建唯一索引:
	CREATE UNIQUE INDEX indexName ON mytable(username(length)) 
	-- 修改表结构的方式添加唯一索引
	ALTER table mytable ADD UNIQUE [indexName] (username(length))
	-- 创建表的时候同时创建唯一索引
	CREATE TABLE `table` (字段1,字段2,……,UNIQUE [indexName] (username(length)));
-- 使用ALTER 命令添加和删除索引
	ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULLALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)。
	ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引,索引值可出现多次。
	ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):该语句指定了索引为 FULLTEXT ,用于全文索引。
	mysql> ALTER TABLE testalter_tbl ADD INDEX (c);  //在表中添加索引
	mysql> ALTER TABLE testalter_tbl DROP INDEX c;  //在 ALTER 命令中使用 DROP 子句来删除索引
-- 使用 ALTER 命令添加和删除主键
	如果想要更改列的类型而不是名称, CHANGE语法仍然要求旧的和新的列名称,即使旧的和新的列名称是一样的
	使用MODIFY来改变列的类型,此时不需要重命名
	mysql> ALTER TABLE testalter_tbl MODIFY i INT NOT NULL;  //确保该主键默认不为空(NOT NULL)
	mysql> ALTER TABLE testalter_tbl ADD PRIMARY KEY (i);  //添加主键索引
	mysql> ALTER TABLE testalter_tbl DROP PRIMARY KEY;  //删除主键
-- MySql删除索引的语法
DROP INDEX [indexName] ON mytable;  //删除表时,该表的所有索引同时会被删除
-- MySql显示索引信息的语法
SHOW INDEX FROM table_name;
-- 索引案例:
	-- 1. 学生表的学生姓名添加一个索引
	create INDEX index_student_sname on student(s_name);
	-- 2. 查看某个表的索引
	show index from student;
	--部分结果说明
		Table:创建索引的表
		Non_unique:索引是否非唯一
		Key_name:索引的名称
		Column_name:定义索引的列字段
		Seq_in_index:该列在索引中的位置
		Null:该列是否能为空值
		Index_type:索引类型
	-- 3. 删除索引
	DROP INDEX index_student_sname on student;
	
-- 创建索引的指导原则
() 按照下列标准选择建立索引的列
1.频繁搜索的列
2.经常用作查询选择的列
3.经常排序、分组的列
4.经常用作连接的列(主键/外键)

() 请不要使用下面的列创建索引
1.仅包含几个不同值的列
2.表中仅包含几行

() 使用索引时注意事项
1.查询时减少使用*返回全部列,不要返回不需要的列
2.索引应该尽量小,在字节数小的列上建立索引
3.WHERE子句中有多个条件表达式时,包含索引列的表达式应置于其他条件表达式之前
4.避免在ORDER BY子句中使用表达式

8.表与表之间的关系、多表查询

# 表与表之间的关系:
一对多关系:一是主表,多是从表。比如部门与员工。
一对一关系:只是增加一个字段。比如人的身份证。
多对多关系:有一个中间表。比如用户与角色。

# 多表查询:语法如下
SELECT<字段名列表>FROM<表名或视图>
[inner join <表名或视图> on 条件]
[WHERE<查询条件>]
[GROUP BY<分组的字段名]
[ORDER BY<排序的列名>[ASCDEsC
[LMIT[位置偏移量,]行数];

# 连接查询
1.交叉连接查询(基本不会使用-得到的是两个表的笛卡尔积) [了解]	
2.内连接查询(使用的关键字 inner join  -- inner可以省略)
内连接原理 : 内连接根据我们连接条件大大的缩小的笛卡尔积的范围;在内连接中只有主外键能够关联上的数据才能被查询出来!
隐式内连接:select * from A,B where 条件;
显示内连接:select * from A inner join B on 条件; (推荐写法)
3.外连接查询(使用的关键字 outer join -- outer可以省略)
外连接可以把关联查询的两张表的一张表作为主表,另外一张作为从表,而外链接使用保证主表的数据完整;
查询原理 : 左外连接查询是以left关键字左边的表为基准表,保证左表数据完整,如果右表没有与左表数据匹配的记录,那么右表将以一条null数据填充查询结果,保证左表的完整
左外连接:select * from A left outer join B on 条件;
右外语法: select * from A right outer join B on 条件;(了解)
-- 案例
	-- 1.查询价格在一万以内名字中包含 '想' 的商品
	隐式内连接:select * from category c,product p where c.cid = p.c_id and p.price <= 10000 and p.pname like '%想%';
	显式内连接:分工明确 不容易写乱套
	select * from category c 
	inner join product p on c.cid = p.c_id -- 此处设置管理
	where p.price < 10000 and p.pname like '%想%'; -- 此处设置条件
	-- 2.查询所有分类商品的个数
	左外连接:
	select c.cname,count(p.c_id) gs from category c
	left join product p on c.cid = p.c_id 
	group by c.cname;

-- 子查询
定义:一条select语句结果作为另一条select语法一部分(查询条件,查询结果,表等)。
语法:select * from 表名 where 查询字段 >|<|= (查询条件,查询结果,表等);
	-- 案例 :  查询和海尔洗衣机同样价格的商品
	连接查询: 没法连接呀,发生在一张表的查询,关联字段也找不到,你叫我怎么连接?啊?怎么连接?
	单行单列子查询:select * from product p where p.price = (select p.price from product p where p.pname like '%海尔%洗衣机%');
	-- 案例 :  查询所有商品的商品类别名称
	单行多列子查询:select * from category where cid in (select DISTINCT c_id from product);
	-- 下面这条语句就是把一个查询结果直接封装为一个虚拟表a表 然后在封装的虚拟表a表的基础上又做查询 这种子查询叫做 多行多列子查询
	多行多列子查询:select * from (select p.*,c.cname from product p inner join category c on p.c_id = c.cid) a where a.price > 10000

9.MySql实战

# 2018年XX市高考成绩管理与分析系统数据库实战
1.数据库结构介绍与准备
2.导入SQL脚本
3.SQL语句实战练习

# 难度 ★  查询各表数据的基本情况
-- 查询地区表数据
select * from area;
-- 查询学校表数据
select * from school;
-- 查询学生表信息
select * from student;
-- 查询学生表信息
select * from `subject`;
-- 查询成绩表数据
select * from result;
-- 查询地区表数据的数据总量
select count(*) from area;
--  查询学校表数据的数据总量
select count(*) from school;
-- 查询学生表数据的数据总量
select count(*) from student;
-- 查询科目表数据的数据总量
select count(*) from `subject`;
-- 查询成绩表数据的数据总量
select count(*) from result;

# 分页查询数据,难度 ★★
-- 查询前五条学生数据
select * from student limit 0,5;
-- 查询5-10条学生数据
select * from student limit 5,5;
-- 查询11-15条学生数据
select * from student limit 10,5;
-- 查询15-20条学生数据
select * from student limit 15,5;
-- 根据以上参数我们能得出以下公式:
-- 1) totalPage = totalCount%pageSize==0? totalCount/pageSize: totalCount/pageSize+1;
-- 2) limit的第一个参数 = (pageIndex-1)*pageSize;
-- 3) limit的第二个参数 = pageSize;

# 连接基础,难度 ★★★
-- 询每个地区的学校信息
select a.a_id,a.a_name,sc.sc_id,sc.sc_name from area a inner join school sc on a.a_id = sc.a_id;
-- 分页查询所有学生的基本信息以及所属院校和所属地区 分页展示 每页10条 展示第1页
select s.*,sc.sc_name,a.a_name from student s
inner join school sc on s.sc_id = sc.sc_id
inner join area a on sc.a_id = a.a_id
limit 0,10;

# 连接进阶,难度 ★★★★
-- 查询语文考试的前十名成绩
select * from `subject` s
inner join result r on s.su_id = r.su_id 
where s.su_name='语文' order by r.r_score desc limit 0,10;
-- 查询总分前十名的成绩
select r.s_id,sum(r.r_score) zf from result r group by r.s_id order by zf desc limit 0,10;
select r.s_id,sum(r.r_score) zf from result r inner join `subject` su on r.su_id = su.su_id
group by r.s_id order by zf desc limit 0,10;
-- 显示上面SQL的考生姓名
select s.*,sum(r.r_score) zf from result r 
inner join `subject` su on r.su_id = su.su_id
inner join student s on s.s_id = r.s_id
group by r.s_id order by zf desc limit 0,10;
-- 显示上面SQL的考生所在学校和所属地区
select s.*,sum(r.r_score) zf,sc.sc_name,a.a_name zf from result r 
inner join `subject` su on r.su_id = su.su_id
inner join student s on s.s_id = r.s_id
inner join school sc on sc.sc_id = s.sc_id
inner join area a on a.a_id = sc.a_id
group by r.s_id order by zf desc limit 0,10;

# 实战基础,难度 ★★★★★
-- 统计一共有多少人参加高考,过一本线(大于等于550分),二本线(大于等于450分),专科线(大于等级250分的)分别有多少人;
	-- 青铜写法
		-- 总人数
		select count(*) from (select * from result group by s_id) a;
		-- 一本人数
		select r.s_id,sum(r.r_score) zf from result r group by r.s_id having zf >=550;
		select count(*) from (select r.s_id,sum(r.r_score) zf from result r group by r.s_id having zf >=550) a;
		-- 二本人数
		select r.s_id,sum(r.r_score) zf from result r group by r.s_id having zf >=450 and zf <550;
		select count(*) from (select r.s_id,sum(r.r_score) zf from result r group by r.s_id having zf >=450 and zf <550) a;
		-- 专科人数
		select r.s_id,sum(r.r_score) zf from result r group by r.s_id having zf >=250 and zf <450;
		select count(*) from (select r.s_id,sum(r.r_score) zf from result r group by r.s_id having zf >=250 and zf <450) a;
		-- 未录取人数
		select r.s_id,sum(r.r_score) zf from result r group by r.s_id having zf <250;
		select count(*) from (select r.s_id,sum(r.r_score) zf from result r group by r.s_id having zf <250) a;
	-- 王者写法
	select 
	count(*) t,
	sum(case when zf >=550 then 1 else 0 end) f,
	sum(case when zf >=450 and zf <550 then 1 else 0 end) s,
	sum(case when zf >=250 and zf <450 then 1 else 0 end) e,
	sum(case when zf <250 then 1 else 0 end) o
	from (select r.s_id,sum(r.r_score) zf from result r group by r.s_id) a;

	上面的写法中除了我们认识的一些SQL语法外还出现了case wen 这种SQL结构:
	case when 判断条件 then 条件成立执行 else 条件不成立执行 end.
	CASE WHEN结构和Java中的f是一样的;
	CASE WHEN就是 if then end就是if的大括号.
	concat方法:select concat(country, "\t",num)as concat string from(将两个字段保存为一个字段)

# 实战高级,难度 ★★★★★★
-- 每个区参数考试人数
select a.*,count(*) from area a
inner join school sc on a.a_id = sc.a_id
inner join student st on sc.sc_id = st.sc_id
inner join (select distinct s_id from result) r on st.s_id = r.s_id
group by a.a_name;
-- 每个区的录取情况
select a.a_name,count(*) t,
sum(case when zf >=550 then 1 else 0 end) f,
sum(case when zf >=450 and zf <550 then 1 else 0 end) s,
sum(case when zf >=250 and zf <450 then 1 else 0 end) e,
sum(case when zf <250 then 1 else 0 end) o
from area a
inner join school sc on a.a_id = sc.a_id
inner join student st on sc.sc_id = st.sc_id
inner join (select s_id,sum(r_score) zf from result group by s_id) r on st.s_id = r.s_id
group by a.a_name;

你可能感兴趣的:(MySQL,mysql,数据库,sql)