having(分组过滤)-->,横向合并、纵向合并
mariadb的查询流程图
服务端命令SQL
style="font-family: 微软雅黑; font-size: medium;">在数据库系统中,SQL语句不区分大小写(建议用大写)
SQL语句可单行或多行书写,以“;”结尾
关键词不能跨多行或简写
用空格和缩进来提高语句的可读性
子句通常位于独立行,便于编辑,提高可读性
注释:
SQL标准:
/*注释内容*/ 多行注释
-- 注释内容 单行注释,注意有空格
MySQL注释:
#
SQL优化
查询时,能不要*就不用*,尽量写全字段名
大部分情况连接效率远大于子查询
多表连接时,尽量小表驱动大表,即小表 join 大表
在千万级分页时使用limit
对于经常使用的查询,可以开启缓存
多使用explain和profile分析查询语句
查看慢查询日志,找出执行时间长的sql语句优化
sql查询:单表查询和多表查询
两张表合并:横向合并、纵向合并
纵向合并:两张表挑出相同的字段进行合并(注意顺序)
范例
SQL查询范例
1、给表的字段名添加别名 select stuid as 学生编号,name 姓名,gender 性别 from students;
2、查询年龄大于40的 select * from students where age >40;
3、查找年龄大于20小于40的 select * from students where age < 40 and age > 20; select * from students where age between 20 and 40;(这种是包含)
4、查询以姓名以X开头的 select * from students where name like 'x%';
5、查找字段中为空值得信息 select * from students where classid is null;
6、查找字段值不为空得信息 select * from students where classid is not null;
7、查找报1,2,6班得学生信息 select * from students where classid in (1,2,6);
8、查找年龄,并去掉重复得年龄 select distinct age from students;
9、查询年龄,去掉重复并排序 select distinct age from students order by age;(默认正序) select distinct age from students order by age desc;(倒叙)
10、统计students表总共有多少行 select count(*) from students;
11、统计age年龄的总和 select sum(age) from students;
12、统计年龄最大的 select max(age) from students;
13、统计男女平均年龄 select gender,avg(age) from students group by gender;
14、分别统计每班的女生男生平均成绩(gender性别classid班级age成绩) select gender,classid,avg(age) from students group by gender, classid;
15、基于上条再统计女生的最大年龄 select gender,max(age) from students group by gender having gender='f'; 备注:分完组后再条件用having不能用where
16、按照课程统计没课考试最好的成绩 select courseid,max(score) as 最好成绩 from scores group by courseid;
17、取排序的前3名 select age from students order by age desc limit 3;
18、基于排序跳过2个显示3个 select age from students order by age desc limit 2,3;
select语句的从句分析顺序:from(过滤表)-->where(过滤行)-->group by(分组)-->having(分组过滤)-->order by(排序)--
多表
1、纵向合并两张表
select stuid as id,name,age,gender from students union select tid,name,age,gender from teachers;
2、基于上条查询 查找age字段大于50的信息
select * from (select stuid as id,name,age,gender from students union select tid,name,age,gender from teachers)as b where b.age >50;
备注:利用了子查询
子查询:
查找比平均年龄大的信息
select name,age from students where age >(select avg(age) from students);
交叉链接
两张表交叉链接组合
select * from students cross join teachers;
内连接
取两张表的交集实现查找出学生对应的老师
select s.name as 学生name,t.name as 老师name from students as s inner join teachers as t on s.teacherid=t.tid;
备注:因为两种表有相同的字段,为了群分开给它加别名as,
左外链接
两张表A 和 B ,
取A表和B表的与A表相关的部分,A加B的一部分
select stuid,s.name,s.age,s.gender,classid,teacherid,tid,t.name,t.age,t.gender from students as s left join teachers as t on s.teacherid=t.tid;
有这样一个表emp
公司人员信息,即对应的领导--(leaderid领导编号)
id | name | leaderid |
1 | xiaoming | null |
2 | wanger | 1 |
3 | zhangsan | 2 |
4 | lisi | 3 |
现在有这样一个需求,查询每个人员对应的领导是谁
把emp表当作两张表来处理,自链接
select e.name as emp,l.name as leader from emp as e left outer join emp as l on e.leaderid=1.id;
>select(选取字段)-->limit(查询限制)-->最终结果
DISTINCT: 数据去重
SQL_CACHE: 显式指定存储查询结果于缓存之中
SQL_NO_CACHE: 显式查询结果不予缓存
show global variables like '%query%';
query_cache_type | ON 表示缓存开启
query_cache_size | 0 表示缓存空间大小,如果为0则不缓存
query_cache_type的值为'DEMAND'时,显式指定SQL_CACHE的SELECT语句才会缓存;其它均不予缓存
缓存并不会缓存所有查询结果,例如select now();就不会缓存
WHERE子句:指明过滤条件以实现“选择”的功能
算术操作符:+, -, *, /, %
比较操作符:=, !=, <>, <=>, >, >=, <, <=
BETWEEN min_num AND max_num
IN (element1, element2, ...)
IS NULL
IS NOT NULL
LIKE:
%: 任意长度的任意字符
_:任意单个字符
RLIKE
逻辑操作符: NOT,AND,OR
GROUP:根据指定的条件把查询结果进行“分组”以用于做“聚合”运算:avg(), max(), min(), count(), sum()
HAVING: 对分组聚合运算后的结果指定过滤条件
ORDER BY: 根据指定的字段对查询结果进行排序:升序ASC 降序:DESC
LIMIT [[offset,]row_count]:对查询的结果进行输出行数数量限制
例如:
select name,age from students where age/2=11;
select name,age from students where age+30>50;
select distinct gender from students;
select name as stuname from students;
select name,classid from students where classid is null;
select avg(age),gender from students group by gender;
select avg(age) as ages,gender from students group by gender having ages>20;
select count(stuid) as NO,classid from students group by classid;
select count(stuid) as NO,classid from students group by classid having NO>2;
select name,age from students order by age limit 10,10; (第一个表示偏移10个,第二个表示取10个)
多表查询:
交叉连接:笛卡尔乘积(最消耗资源的一种查询) 例如:select * from students,teachers; 如果students有20行,teachers也有20行,则显示400行
内连接:
等值连接:让表之间的字段以“等值”建立连接关系;
不等值连接
自然连接
自连接
外连接:
左外连接 例如:FROM tb1 LEFT JOIN tb2 ON tb1.col=tb2.col
右外连接 例如:FROM tb1 RIGHT JOIN tb2 ON tb1.col=tb2.col
等值连接:
select s.name as studentname,t.name as teachername from students as s,teachers as t where s.teacherid=t.tid;(这个够复杂)
select s.name,c.class from students as s,classes as c where s.classid=c.classid;
左外连接:
select s.name,c.class from students as s left join classes as c on s.classid=c.classid;
以左表作为基准
select s.name,c.class from students as s right join classes as c on s.classid=c.classid;
以右表为基准
子查询:在查询语句嵌套着查询语句,基于某语句的查询结果再次进行的查询 (mariadb对子查询优化不够,建议一般情况不使用)
select name,age from students where age>(select avg(age) from students);
select name,age from students where age in (select age from teachers);
select s.ages,s.classid from (select avg(age) as ages,classid from students where classid is not null group by classid) as s where s.ages>30;
联合查询:UNION
select name,age from students union select name,age from teachers;
本文由9159.com发布于操作系统,转载请注明出处:having(分组过滤)-->,横向合并、纵向合并
关键词:
下一篇:没有了