五种查询
- where
- group
- havding
- order by
- limit
在使用的时候必须按照这五个查询方法的顺序使用,否则语法不通过;即 where group having order by limit
标准的 SQL 的解析顺序为: (1).FROM 子句, 组装来自不同数据源的数据 (2).WHERE 子句, 基于指定的条件对记录进行筛选 (3).GROUP BY 子句, 将数据划分为多个分组 (4).使用聚合函数进行计算(max avg min ...) (5).使用 HAVING 子句筛选分组 (6).计算所有的表达式(limit)
select
name
from
score
where
name
not
in
(
select
name
from
score
where
score<
80
)
group
by
name
;
举例说明: 在学生成绩表中 (暂记为 tb_Grade), 把 "考生姓名" 内容不为空的记录按照 "考生姓名" 分组, 并且筛选分组结果, 选出 "总成绩" 大于 600 分的. select 考生姓名, max(总成绩) from tb_Grade where name is not null group by s_name having 总成绩>600 order by max(从成绩)
在学生成绩表中 把 "考生姓名" 内容不为空的记录按照 "考生姓名" 分组, 并且筛选分组结果, 选出 "总成绩" 大于 600 分的. 分析句子:把 姓名分组 选 总成绩 条件:姓名不为空 max 大于 600 标准顺序的 SQL 语句为: select 考生姓名, max(总成绩) as max总成绩 from tb_Grade where 考生姓名 is not null group by 考生姓名 having max(总成绩) > 600 order by max总成绩 在上面的示例中 SQL 语句的执行顺序如下: (1). 首先执行 FROM 子句, 从 tb_Grade 表组装数据源的数据 (2). 执行 WHERE 子句, 筛选 tb_Grade 表中所有数据不为 NULL 的数据 (3). 执行 GROUP BY 子句, 把 tb_Grade 表按 "学生姓名" 列进行分组 (4). 计算 max() 聚集函数, 按 "总成绩" 求出总成绩中最大的一些数值 (5). 执行 HAVING 子句, 筛选课程的总成绩大于 600 分的. (7). 执行 ORDER BY 子句, 把最后的结果按 "Max 成绩" 进行排序 (7).使用 ORDER BY 对结果集进行排序 |
Mysql常用命令:
- 登录:mysql 启动mysql服务 cmd —— net start mysql(这个是服务名字)
- mysql -h localhost -u root -p (密码)
- 敲错 命令用\c回到编辑界面
- 查看数据库有多少个库:show databases;
- 创建 一个库:create database kuname;
- 使用一个库:use tablename;(不用show也行,直接上来就use,前提是你对数据库很了解)
- 显示表:show tables;(注意 是多张表:tables)
- 删除一个库:dorp database kuname;\\\\\\\\\\\mysql 不准许修改自己的数据库的名字
- mysql中1064是语法错误;
- 修改表名:rename table oldtablename to newtableneme(库名是不能改的)
- 删除一个表:你猜怎么删除呢?
- 查看表结构:desc tablename
- 给一个表增加一个字段:alter table tablename add 字段名 类型;例如:alter table admin add age tinyint ;
- 如何设置字段类型为无符号的呢?:声明的时候在字段类型后面加上unsigned;(无符号的)
- tinyint(M) unsigned zerofill
- copy 一个已经存在的表结构: create table tablename like 已经存在的表的名字 ,这样创建出来的表没有数据,知识结构相同。
其中 M代表宽度,但是只有在zerofill时才有效,
unsigned : 无符号
zerofill :0填充 例如:0001 0002 0003 、
char和varchar的区别:
char(M) 表示定长字符串,如果实际存储不够M个,则后面加空格补齐,取出来的时候,在把空格去掉,(所以你真想存空格的时候是存不上的)
varchar(M)变长字符串,
速度上:char定长更快一些 选择原则:1,空间利用率 2.速度
text:??
YEAR类型是一个单字节类型用于表示年。
MySQL以YYYY格式检索和显示YEAR值。范围是1901到2155。
可以指定各种格式的YEAR值:
· 四位字符串,范围为'1901'到'2155'。
· 四位数字,范围为1901到2155。
· 两位字符串,范围为'00'到'99'。'00'到'69'和'70'到'99'范围的值被转换为2000到2069和1970到1999范围的YEAR值。
· 两位整数,范围为1到99。
1到69 被转换为2001到2069
70到99被转换为1970到1999范围的YEAR值。
请注意两位整数范围与两位字符串范围稍有不同,因为你不能直接将零指定为数字并将它解释为2000。你必须将它指定为一个字符串'0'或'00'或它被解释为0000。
· 函数返回的结果,其值适合YEAR上下文,例如NOW()。
非法YEAR值被转换为0000。
类型 |
字节 |
最小值 |
最大值 |
|
|
(带符号的/无符号的) |
(带符号的/无符号的) |
TINYINT |
1 |
-128 |
127 |
|
|
0 |
255 |
SMALLINT |
2 |
-32768 |
32767 |
|
|
0 |
65535 |
MEDIUMINT |
3 |
-8388608 |
8388607 |
|
|
0 |
16777215 |
INT |
4 |
-2147483648 |
2147483647 |
|
|
0 |
4294967295 |
BIGINT |
8 |
-9223372036854775808 |
9223372036854775807 |
|
|
0 |
18446744073709551615 |
create table admin(
id int primary key,
username varchar(20),
password varchar(20)
)
如何理解where:把where条件当成一个表达式和每一行对比看是否成立,where 只对硬盘上的表起作用,查询出来的放在缓冲区内的不起作用。
如何理解select 后面的列呢:把列名当成变量来理解,变量是能运算的,
查询每个栏目下积压的货款(商品库存*价格)
select goods_id ,sum(goods_num* goods_pirce) from goods group by goods_id;
查询每个栏目积压的货款,并且货款超过两万的栏目;
select goods_id ,sum(goods_pirce* goods_number) as huokuan from goods group by goods_id having huokuan > 20000;
模糊查询:like
like 后面加条件 %通配任意字符 _通配单个字符
之Group by
把 行 按 字段 分组 (关键字:max min sum count ....)
- 查询最贵的商品的价格 select max(goods_price) from goods;
- 查询最大商品编号的商品 select max(goods_id) from goods;
- 查询最便宜的商品的价格 select min(goods_id) from goods;
- 查询所有商品的总库存量 select sum(goods_number) from goods;
- 查询每个栏目下最贵商品的数量 select cat_id ,max(shop_price) from goods group by cat_id;
- 每个栏目下商品种类 select cat_id count(*) from goods group by cat_id;
Limit 的使用
在语句的最后面,起到线限制条目的作用
limit [offset]N
offset:偏移量(可选参数,如果不写,默认为0.从第一条开始选)
N:取出条目(必选参数)
eg:取出数据库中最贵的商品:
select goods_id ,goods_name from goods order by goods_price desc limit 1;
难度点的:去出每个栏目中最贵的商品
select goods_id,goods_name from goods group by goods_id order by desc limit 1;
子查询:
where型子查询:把内层的查询结果当作外层查询的比较条件
from型子查询:把内层的查询结果当成一张临时表,共外层sql再次查询
exists型子查询: 把外层的查询结果拿到内层,看内层的查询条件是否成立
EG:查询最新发布的商品:
select goods_id,goods_name from goods where goods_id = (select max(goods_id) from goods); ????传说中的子查询;
查询 每个 栏目 最贵 的商品:
第一步:先查出 最贵 顺带栏目 的:select max(goods_price) from goods group by goods_id ;
第二步:查询 select goods_id ,goods_name,goods_price where goods_price in (select max(goods_price) from goods group by goods_id);
联合查询:union
联合查询就是两张表或多张不同得表联合查询
查询条件就是:两张表查询出来的列数一致。表的机构可以不一致。
如果两张表联合查询出来的数据有相同的行和数值,不指定union的条件情况下会自动去重复,如果不需要去重则加上all
eg:select * from a union select * from b (去重)select * from a union all select * from b (不去重)
取两张表,并把相同的字段的值相加:
select id ,sum(number) from (select * from a union all select * from b) as flag group by id;
如果字句后面后order by 或limit 时 两个字句必须用()扩起来。
order by 配合limit 使用的时候才有意义,如果没有配置limit,order by 会被语法分析器去掉。就想where 1 恒成立时 不影响 性能;
增加列:
增加列,默认在表的后一列;可以用after类声明新增的列在哪一列后面;第一类用first
alter table tablename add 列名 int *******;
删除列
alter table tablename drop 列名 ;
修改列:alter table tname change 被修改的列名 声明新列 :alter table m change m mmm int ;
视图:什么是视图???如果
视图是由查询结果生成的一张虚拟表;
create view as select 语句 。
修改视图:和创建一样,把create换成alter ,实质就是覆盖掉旧的视图;
- 视图与表的关系:
- 如果表的数据改变了, 那么视图的数据肯定也改变了。
- 视图修改会影响表,但是视图并不总是能增删改的。
- 当视图的数据与表数据一一对应的情况下,这个时候修改视图会对表的有影响。同时,对于insert时,视图还应必须包含没有默认值的列。
为什么要有视图:
- 方便简化查询,如果总是需要一个查询结果做复杂查询的时候。
- 进行权限控制,因为有有的表不方便给别人看。这样就可以创建一个视图给别人看。
- 大数据分表是可以用:比如表的行数超过很多时:超过200万 变慢的情况就比较明显了,这个时候就可以把
事务:四个特性ACDI特性
- 指一组操作,要么都执行完,要么不执行--------原子性(原子的不可拆分性)(Atomicity)
- 事务发生之前和发生之后数据的总额一定要一致-------一致性(Consistenty)
- 所有操作没有完成前,其他会话不能看到事务的过程-----------隔离性(lsolation)
- 事务的影响不能撤销------------持久性(Durability)
如果出现了错误,事务也不准许撤销,只能通过补偿性事务。
数据库备份
1 增量备份
2.整体备份
常用备份命令:
- 导出一个库(以库为单位):mysqldump -u root -p -B kuname1 kuname2 kuname3 > D:\\kuname.sql
- 导出所有库:mysqldump -u root -p -A >路径/备份名.sql
- 导出一个库下所有的表(以表为单位):mysqldump -u root -p kuname >D:\\kuname.sql
- 导出库下的一个表:mysqldump -u root -p kuname t_name1 t_name2 t_name3 >D:\\t_name.sql
- 以库为单位恢复:Mysql> source D:\\***.sql; 一句话ok(已经登录的情况下)
- 一表为单位恢复:Mysql> use ku_name
Mysql> source D:\\***.sq;(分两步)
索引:针对数据所建立的目录
好处:加快查询速度
坏处:降低增删改的速度
索引的创建原则:
1.不要过度索引
2.在where件最频繁的地方加索引
3.尽量索引散列值,过于集中的值索引意义不大
普通索引:index 加快了查询速度
唯一索引:unique 行上的值不能重复
主键索引: primary key 不能重复
全文索引:fulltext (对文章内部索引,不是模糊查询,模糊查询是一行一行的找,效率很低)
查看一张表的索引:
show index from t_name;
建立索引:
alter table 表名 add primary key (列名)
alter table 表明 add index/unique/fulltext 索引名(列名)不写索引名默认和列名相同
删除索引
alter table 表名 drop index 索引名;
经典面试题:
create table m (
mid int primary key auto_increment,
hid int ,
gid int ,
mres varchar(10),
matime date
);
insert into m
(hid,gid,mres,matime)
values
(1,2,'2:0','2006-05-21'),
(2,3,'1:2','2006-06-21'),
(3,1,'2:5','2006-06-25'),
(2,1,'3:2','2006-07-21');
create table t(
tid int,
tname varchar(10)
);
insert into t
values
(1,'国安'),
(2,'申花'),
(3,'曼联');
select t1.tname,mres,t2.tname,matime from
m left join t as t1
on m.hid = t1.tid
left join t as t2
on m.gid = t2.tid
where matime between '2006-0601' and '2006-07-01';