在使用BETWEEN时,必须指定两个值——所需范围的低端值和高端值。这两个值必须用AND关键字分隔。BETWEEN匹配范围中所有的值,包括指定的开始值和结束值。
9.2:空值检查,is null,is not null
例如:select * from student where sname is not null #检索sname不为空的所有行。
9.3:组合WHERE子句,以AND子句的方式或OR子句的方式使用
select * from course where cno between 'c001' and 'c004'
select * from course where cno>='c001' and cno <='c004' (两句使用结果一样)
and逻辑操作符,判断cno的范围,和between..and...使用效果类似。where 之间可以嵌套多个and或者or。
9.3.1:在and和or操作符中,and的优先级超过or,所以在使用中尽量将or的字句用()括起来。
例如:select cno,score from sc where (cno='c001' or cno='c002') and score>80 # 检索cno为c001和c002的,并且score大于80的。
9.4:IN操作符。 IN操作符用来指定条件范围,范围中的每个条件都可以进行匹配。
例如:select * from sc where sno in ('s001','s005') #检索sno在数s001到s005之间,与or的功能一样。
in操作符一般比or执行速度快
9.5:not操作符.WHERE子句中的NOT操作符有且只有一个功能,那就是否定它之后所跟的任何条件。
10:用通配符进行过滤。(一般和like操作符搭配使用)
通配符(wildcard) 用来匹配值的一部分的特殊字符。
10.1:百分号(%)通配符,在搜索串中,%表示任何字符出现任意次数。
例如:select * from student where sname like '陈%' # 检索姓陈的所有学生。(通配符可以在中间,开头或者结尾)
%代表搜索模式中给定位置的0个、1个或多个字符
注意NULL 虽然似乎%通配符可以匹配任何东西,但有一个例外,即NULL。
10.2:下划线(_)通配符。
下划线的用途与%一样,但下划线只匹配单个字符而不是多个字符。
例如:select * from student where sname like '_三' #只能检索 第二个字符是三的学生,比如张三。
注意:
正如所见,MySQL的通配符很有用。但这种功能是有代价的:通配符搜索的处理一般要比前面讨论的其他搜索所花时间更长。这里给出一些使用通配符要记住的技巧。
10.2.1不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他操作符。
10.2.2在确实需要使用通配符时,除非绝对有必要,否则不要把它们用
10.2.3 在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起来是最慢的。
10.2.4仔细注意通配符的位置。如果放错地方,可能不会返回想要的数
11:mysql算数操作符
+加 -减 *乘 /除
例如:select danjia,num,danjai+num from price #检索单价乘以数量后的总价
11.1:测试运算,虽然SELECT通常用来从表中检索数据,但可以省略FROM子句以便简单地访问和处理表达式。(体现sql作为检索数据语言的特性)
select trim('q') #输出q select 4*5 输出20
11.2:而SELECTNow()利用Now()函数返回当前日期和时间
12:汇总数据
AVG()返回某列的平均值,COUNT()返回某列的行数,MAX()返回某列的最大值,MIN()返回某列的最小值,SUM()返回某列值之和
12.1:AVG()函数忽略列值为NULL的行。
例如:select avg(danjia) from price #值统计单价不为空的数据的平均值(null的行值也不计)
12.2:COUNT()函数进行计数。可利用COUNT()确定表中行的数目或符合特定条件的行的数目。
例如:select count(id) from price #统计价格表的商品数量。
注意:
使用COUNT(column)对特定列中具有值的行进行计数,忽略NULL值。
12.3:虽然MAX()一般用来找出最大的数值或日期值,但MySQL允许将它用来返回任意列中的最大值,包括返回文本列中的最大值。在用于文本数据时,如果数据按相应的列排序,则MAX()返回最后一行。(MAX()函数忽略列值为NULL的行。)
例如:select max(num) from price #找出价格表中数量最大的
12.4:MIN()函数和max函数一样的性质,不同的是取最小的值。
例如:select min(num) from price #找出价格表中数量最小的
12.5:SUM()用来返回指定列值的和(总计)(SUM()函数忽略列值为NULL的行。)
例如:select sum(num) from price #找出商品的数量之和
12.6:聚集不同值distinct(去重)
ALL参数不需要指定,因为它是默认行为。如果不指定DISTINCT,则假定为ALL。
例如:select sum(DISTINCT danjia) from price #检索单价去重后的总和
注意:
如果指定列名,则DISTINCT只能用于COUNT()。DISTINCT不能用于COUNT(*),因此不允许使用COUNT(DISTINCT),否则会产生错误。类似地,DISTINCT必须使用列名,不能用于计算或表达式。
12.6:组合聚集函数
例如:select count(danjia),max(danjia),min(danjia),avg(danjia) from price #检索价格表中的单价数量,单价最大值,单价最小值,单价的平均值。
注意:
聚集函数用来汇总数据。MySQL支持一系列聚集函数,可以用多种方法使用它们以返回所需的结果。这些函数是高效设计的,它们返回结果一般比你在自己的客户机应用程序中计算要快得多。
13:数据分组(group by)分组是在SELECT语句的GROUP BY子句中建立的。
返回学生重名的数据?返回每个供应商提供的产品数目怎么办?或者返回只提供单项产品的供应商所提供的产品,或返回提供10个以上产品的供应商怎么办?
例如:select sname,count(sname) as s from student GROUP BY sname #对学生表的sname字段进行分组,得到每个名字和数量。
13.1:使用rollup,使用WITH ROLLUP关键字,可以得到每个分组以及每个分组汇总级别(针对每个分组)的值
13.2:过滤分组。(having字句)
HAVING非常类似于WHERE。事实上,目前为止所学过的所有类型的WHERE子句都可以用HAVING来替代。唯一的差别是WHERE过滤行,而HAVING过滤分组。
HAVING支持所有WHERE操作符
例如:SELECT sname,count(sname) from studentGROUP BY sname HAVING count(sname)>1 #通过学生的名字分组,过滤出名字大于一的组(帅选出重名的学生)
13.2:HAVING和WHERE的差别
WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。这是一个重要的区别,WHERE排除的行不包括在分组中。这可能会改变计算值,从而影响HAVING子句中基于这些值过滤掉的分组
13.3:分组和排序
13.3.1:order by和group by 的区别
ORDER BY GROUP BY
- 排序产生的输出 分组行。但输出可能不是分组的顺序
- 任意列都可以使用(甚至 只可能使用选择列或表达式列,而且必须使用每个选择列表达式
- 非选择的列也可以使用)
- 不一定需要 如果与聚集函数一起使用列(或表达式),则必须使
注意:
group by 默认是分组的顺序,最后搭配order by 使用可以得到我们实际想要的顺序输出。
14:子查询(嵌套在其他查询中的查询)
例如:SELECT sno,score from sc where sno in (select sno from student where sno in ('s001','s002')) # 查询学号为s001和s002的学生的学号,成绩(在学生表和成绩表里查询)
相当于利用子查询进行过滤,
14.1:列必须匹配
在WHERE子句中使用子查询(如这里所示),应该保证SELECT语句具有与WHERE子句中相同数目的列。通常,子查询将返回单个列并且与单个列匹配,但如果需要也可以使用多个列。(例如上个语句中sno匹配)
15:联结(join)表
主键:作为表信息的唯一标识(具有唯一性)
外键:外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的关系
15.1:创建联结 (要理解联结不是物理实体。换句话说,它在实际的数据库表中不存在。联结由MySQL根据需要建立,它存在于查询的执行当中。)
例如:SELECT student.sno,student.sname,sc.score from student,sc where student.sno=sc.sno #查询所有学生的成绩(学生表和成绩表联结)
注意:在使用联结时必须限定列名(如上sql句标黄部分)
15.2:笛卡儿积:由没有联结条件的表关系返回的结果为笛卡儿积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数
所以要保证所有的联结都有where字句,这样的结果才是正确数据
笛卡尔积又称叉联结的笛卡尔积的联结类型
15.3:内部联结(inner join),又称等值联结。
例如:SELECT student.sno,student.sname,sc.score from student INNER JOIN sc on student.sno=sc.sno #等同上面sql语句(查询所有学生的成绩)
15.4:使用别名(列名,表名,计算字段)
例如:SELECT a.sno,b.score from sc as a,sc as b where a.sno=b.sno and a.cno='c001' and b.cno='c002'
#查询学过课程c001和c002的学生的学号和成绩(一张表两次使用)
16:不同类型的联结
16.1:自联结
例如:SELECT a.sno,b.score from sc as a,sc as b where a.sno=b.sno and a.cno='c001' and b.cno='c002'
很多时候处理联结远比处理子查询快得多
16.2:内部联结(inner join):
例如:SELECT st.sno,st.sname,s.score from student as st INNER JOIN sc as s on st.sno=s.sno #查询所有学生的成绩(两个表为主)
16.3:外部联结( outer join)
16.3.1:左外部联结
例如:SELECT st.sno,st.sname,s.score from student as st LEFT OUTER JOIN sc as s on st.sno=s.sno(左表表为主)
#查询所有学生(包括没有成绩的学生)的成绩,没有成绩的学生的成绩为null
16.3.2:右外部联结
例如:SELECT st.sno,st.sname,s.score from student as st RIGHT OUTER JOIN sc as s on st.sno=s.sno(右边表为主)
#查询所有学生(只包括有成绩的学生)的成绩。这里等同于内部联结
17:组合查询(执行多个查询(多条SELECT语句),并将结果作为单个查询结果集返回)
17.1:创建组合查询(可用UNION操作符来组合数条SQL查询)
例如:
SELECT st.sno,st.sname,s.score from student as st
INNER JOIN sc as s
on st.sno=s.sno
WHERE s.score>60
UNION
SELECT st.sno,st.sname,s.score from student as st
INNER JOIN sc as s
on st.sno=s.sno
WHERE s.cno='c001'
等同于
SELECT st.sno,st.sname,s.score from student as st
INNER JOIN sc as s
on st.sno=s.sno
WHERE s.score>60 OR
s.cno='c001'
注意:
UNION中的每个查询必须包含相同的列、表达式或聚集函数(不过各个列不需要以相同的次序列出)。
UNION从查询结果集中自动去除了重复的行(换句话说,它的行为与单条SELECT语句中使用多个WHERE子句条件一样)
(使用UNION ALL,MySQL不取消重复的行)
SELECT语句的输出用ORDER BY子句排序。在用UNION组合查询时,只能使用一条ORDER BY子句,它必须出现在最后一条SELECT语句之后。对于结果集,不存在用一种方式排序一部分,而又用另一种方式排序另一部分的情况,因此不允许使用多条ORDER BY子句。
18:插入数据(insert into )
插入一条
INSERT INTO price VALUES(
4,26,7
)
插入多条
INSERT INTO price VALUES(
5,32,11
),
(6,36,14
)
多条插入数据的时候可以一条一条的插入,也可以直接全部插入(推荐使用全部一次插入)
MySQL用单条INSERT语句处理多个插入比使用多条INSERT语句快。
18.1:INSERT SELECT将查询的结果插入到表中
例如:INSERT INTO price(id,danjia,num) SELECT id,danjia,num from price
19:更新表(update set)搭配where使用
19.1:更新表中特定的行
例如:UPDATE price set danjia=35 where id=6 #将ID为6的行的danjia字段修改为35
19.1.1:更新表中特定行的几个字段
例如:UPDATE price set danjia=35,num=4 where id=6 #将ID为6的行的danjia和num字段修改为,35,7.
19.2:更新表中全部的行
例如:UPDATE price set danjia=35 #将所有的行的danjia都修改为35
亦可以在where后加多行,同时修改多行,但是只要有一行更新信息错误就会全部不更新(可使用IGNORE关键字,即使发生错误,也会继续更新正确的信息)
update设置null去除列中的值(为了删除某个列的值,可设置它为NULL(假如表定义允许NULL值))。
20:删除数据(delete)
DELETE不需要列名或通配符。DELETE删除整行而不是删除列。为了删除指定的列,请使用UPDATE语句。
20.1:删除表中特定的行,
例如:delete from price where id=6 #删除ID为6的行
20.2:删除表中全部的行
例如:delete from price #删除price表所有的行
等同于
truncate price
TRUNCATE TABLE(TRUNCATE实际是删除原来的表并重新创建一个表,而不是逐行删除表中的数据)。
21:创建视图
CREATE VIEW dhsj
AS
SELECT * from student
#将学生表作为一个视图dhsj,可以直接在视图dhsj中检索学生表的信息.
视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。
22:delete,truncate,drop的区别
- 在速度上,一般来说,drop> truncate > delete。
- 在使用drop和truncate时一定要注意,虽然可以恢复,但为了减少麻烦,还是要慎重。
- 如果想删除部分数据用delete,注意带上where子句,回滚段要足够大;如果想删除表,当然用drop;
- 如果想保留表而将所有数据删除,如果和事务无关(不能回滚),用truncate即可;
- 如果和事务有关,或者想触发trigger,还是用delete;
- 如果是整理表内部的碎片,可以用truncate跟上reuse stroage,再重新导入/插入数据。