9.汇总数据:
聚集函数:聚集函数运行在行组上,计算和返回单个值的函数
SQL给了五个聚集函数:
AVG(),返回某列的平均值
COUNT(),返回某列的行数
MAX(),返回某列的最大值
MIN(),返回某列的最小值
SUM(),返回某列值之和
聚集函数的用法,例如SUM,都是SELECT SUM(*) FROM talbe_name;
聚集不同值:
DISTINCT:删除重复的行,
10.数据分组
GROUD BY 关键字
SELECT vend_id,COUNT(*) AS num_prods
FROM Products
GROUP BY vend_id;
输出:
vend_id num_prods
BRS0 3
DLL01 2
FNG01 4
这样就看出vend_id有几个了
需要注意的是,GROUP BY 要出现在WHERE 之后,ORDER BY之前
10.1 过滤分组
HAVING:不用WHERE是因为WHERE只是过滤指定的是列而不是分组,大部分WHERE语句都可以用HAVING来代替,HAVING也支持WHERE的操作符
SELECT cust_id,COUNT(*) AS orders FROM Orders GROUP BY cust_id HAVING COUNT(*) >= 2;
这条SQL语句就过滤了COUNT(*) >=2的语句,而在这里WHERE语句是不起作用的,因为过滤是基于分组聚集值而不是特定的行值
HAVING和WHERE的区别在于WHERE在分组前过滤,而HAVING 在数据分组后进行过滤,而WHERE排除的行不包括在分组中,这可能改变计算值,从而影响HAVING语句的计算
10.4.分组和排序
ORDER BY:将结果按照指定的列排序,一般放在语句的最后
10.5.SELECT子句的顺序
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
SELECT 语句次序要按照上面的顺序
11.子查询
子查询我看来还是说把另外一个查询当作输入(或者表来查询)比如SELECT * FROM (SELECT id from student),没什么神奇的
12.表联接
相同的数据放在同一个表里面不是好的设计,所以需要把一些数据分开,关系表的设计就是要把信息分解成多个表,一类数据一个表,各表通过常用的值互相关联
比如要设计一个供应商信息的表,可以把供应商的信息和产品信息分开,这样的话不仅节省空间和时间,如果供应商信息改变,只要更改供应商信息的表,而且数据处理更简单
,这个就是所谓的关系数据库
内部联接
示例:如上面例子,有两个表,一个表是厂商信息,一个表是产品信息
SELECT vend_name,prod_name,prod_price FROM Vendors,Products WHERE Vendors.vend_id = Products.vend_id
在我们联接两个表的时候,实际上是将第一个表中的每一行与第二个表做匹配,而WHERE作为过滤条件
INNER JOIN:
SELECT vend_name,prod_name,prod_price FROM Vendors INNSER JOIN Products ON Vendors.vend_id = Products.vend_id
功能跟上面那句一样,但规范首选INNER JOIN语法
联接表非常耗费资源,不要连接不必要的表
外部联接:
就是包含了那些相关表中没有关联行的行,比如对每个客户下了多少订单计数,包括没有下订单的客户
假设一个表中有客户1,2,3,另外一个表中有客户的订单,其中没有2的信息,如果我们使用INNER JOIN查询,结果会返回
1,订单
3,订单
如果使用OUTER JOIN,会返回
1,订单
2,NULL
3,订单,其中有LEFT JOIN和RIGHT JOIN,使用LEFT JOIN表示从子句的左边选择行,RIGHT JOIN则表示右边,有的SQL也用WHERE ID *= ID表示左联接,=*表示右联接
14,UNION
假设有两个表,一个表里面存有学生考试数据,我们要找出所以学生成绩在85以上并且在A学校的所有学生的成绩,我们可以这样
SELECT * FROM student WHERE grade > 85
UNION
SELECT * FROM student WHERE school = 'A'
功能类似与
SELECT * FROM student WHERE grade > 85 OR school = 'A'
在使用UNION的时候,自动去除重复的行,如果想返回所有匹配的行,可以使用UNION ALL而不是UNION
在使用UNION可以使用ORDER BY来排序,ORDER BY 最后一个SELECT语句,但是ORDER BY对所有的查询生效
15.INSERT 语句
INSERT 语句除了正常的插入,还可以插入到SELECT 语句里面
比如我想把A表的学生信息插入到B表的学生信息里面,可以这样写
INSERT INTO student_B(name,age,sex) SELECT name,age,sex FROM student_A
SELECT * INTO student_A FROM studen_B的意思是把student_B的数据插入student_A
17,视图:
所谓视图我觉得更像是编程语言中的宏定义,把一句SQL语句define成一个名字,比如我们有SELECT * FROM student;这样我们需要每次都输入这个查询语句,如果我们把这句命名为show,那么我们只需要输入show就可以执行查询语句,比如
CREATE VIEW show AS SELCT * FROM studnet;
当然类似与C语言的宏定义,每次使用视图都是查询一次数据库,宏在C语言中会造成代码膨胀,如果每次需要这样数据都查询一下数据库,会造成性能下降(不知道是否有办法把查询存储在一个地方??)
SLELCT name FROM show;有点类似与SELECT name FROM (SELECT * from student);
18.存储过程
存储过程类似与C语言的函数
语法:
DELIMITER //
CREATE PROCEDURE query(OUT param INT)
BEGIN
SELECT COUNT(*) INTO param FORM t;
END
DELIMITER ;
DELIMITER 主要是把分解符改成//,如果没有这据,会导致MYSQL遇到;后就会直接认为到;是一句完整的MYSQL 语句
19.事务处理
事务处理有事务(TRANSACTION),指一组SQL语句
回退,rollback,撤销SQL语句(不包括SELECT,CREATE,DROP)
提交,COMMIT
保留点,savepoint与回退所有不同,可以对事务处理中的某个点进行回退