mysql基础-查询语句select使用
1.查询不重复记录
select distinct deptno from emp;
2.条件查询
select * from where deptno=1;
select * from where deptno=1 and sal<2000;
3.排序和限制
1>常用取出按照某个字段进行排序后的记录结果,用关键字order by.
desc 降序,asc 升序,默认是升序
select * from emp order by sal;
select * from emp order by sal desc;
2>对于排序后相同的字段进行再次排序
select * from emp order by sal, deptno desc;
3>对于排序后的记录只显示一部分使用limit
select * from tbname......[limit 偏移量,记录行数]
例子:
select * from emp order by sal limit 3;
select * from emp order by sal limit 2,3;从第三条开始
备注:
默认起始偏移量为0,只写记录行数就行
4.聚合
聚合一般用于数据统计
语法:
select [field1,field2..]fun_name
from tbname
[where where_conditon]
[group by field1,field2..[with rollup]]
[having where_condition]
参数说明:
fun_name 表示要做的聚合操作,也就是聚合函数,常用的有sum(求和)\count(*)(记录数)\max(最大值)\min(最小值).
group by 关键字表示和聚合的字段,比如按照部门分类统计员工数量,group by后就写部门
with rollup 表示对分类聚合后的结果进行再汇总,记录是上面所有记录的总和。
having 表示对分类后的结果进行条件过滤
备注:
having对聚合后的结果进行过滤,where是在聚合前先进行过滤
有必要的话可以先where后进行聚合操作可以提高效率
例子:
1>统计公司中的总人数
select count(1) as c from emp;
2>统计各个部门的人数
select deptno,count(1) from emp group by deptno;
3>既要统计各部门人数,又要统计总人数
select deptno,count(1) from emp group by deptno with rollup;
4>统计人数大于1的部门
select deptno,count(1) from emp group by deptno having count(1)>1;
5>统计公司所有员工的薪水总额\最高和最低
select sum(sal),max(sal),min(sal) from emp;
6>寻找雇员工数超过两个的部门的最高薪水和最低薪水
select bumen,max(xinshui),min(xinshui) from yuangong
group by bumen
having count(*)>2 //count(*表示汇总后各部门的人数-总记录数,因为count(*)条件在having后)
order by bumen;
7>寻找雇员平均工资大于3000的部门的最高和最低薪水
select bumen,max(xinshui),min(xinshui) from yuangong
group by bumen
having avg(xinshui)>3000
order by bumen;
8>使用GROUP_CONCAT()函数可以很好的把分组情况表示出来。
例子:
显示所有部门员工的名字,按部门分组显示
select bumen,group_concat(name) form yuangong group by bumen;
9>各部门的男女的数量
select bumen,sex,count(*) from yuangogn group by bumen,sex;
10>各部门的年龄大于25的男女数量
select bumen,sex,count(*) from yuangong where age>25 group by bumen,sex;
11>年龄大于25,各部门的男女的数量总和大于10 的男女数量
select bumen,sex,count(*) from yuangong where age>25 group by bumen,sex having sum(*)>10;
12>求每个部门的平均薪资
select user_id,round(avg(ifnull(sc_id,0)),2) as avg from sc group by user_id;
5.表连接
内连接: 只连接匹配的行
左外连接: 包含左边表的全部行(不管右边的表中是否存在与它们匹配的行),以及右边表中全部匹配的行
右外连接: 包含右边表的全部行(不管左边的表中是否存在与它们匹配的行),以及左边表中全部匹配的行
全外连接: 包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行。
交叉连接: 生成笛卡尔积-它不使用任何匹配或者选取条件,而是直接将一个数据源中的每个行与另一个数据源的每个行都一一匹配
效率问题:
1.inner join比left join快
注:inner join 内连接等价于下面的sql: SELECT A.name, B.address FROM A, B WHERE A.id = B.A_id所以一般要用一般的连接就可以了.
2.连接字段建索引
__________________________________________________________________
1>内连接:仅选出两张表互相匹配的记录,A,B表中至少有1个匹配时,才返回行。两表的交集
例子:
如果两张表中对应的字段一定有对应使用内连接
select ename,deptname from emp,dept where emp.deptno=dept.deptno;
select A.name,B.address from A inner join B on A.id = B.A_id
__________________________________________________________________
2>左连接:包含所有左边表中的记录甚至是右边表中没有和它匹配的记录
select ename,deptname from emp left join dept on emp.deptno=dept.deptno;
__________________________________________________________________
3>右连接:包含所有的右边表中的记录甚至是左边表中没有和他匹配的记录,和左连接类似可以互相转化
select ename,deptname from dept right join emp on emp.deptno=dept.deptno;
备注:
链接都是以on作为条件的
6.子查询
某些情况下需要查询的时候,需要的条件是另一个select语句的结果,这时候用子查询.
用于子查询的关键字包括(in|not in|=|!=|exists|not exists)等.
例子:
1>in 条件记录为多个
select * from emp where deptno in(select deptno from dept)
2.= 条件记录为1
select * from emp where deptno=(select deptno from dept where id=1);
备注:
某些情况下表连接可以替代子查询用于优化
7.记录联合
有时候需要将两张表的记录查询出来之后合并到一起显示
union 合并到一起并且进行一次distinct去重
union all 合并到一起显示
select deptno from emp
union
select deptno from dept;
8.子查询和表连接还有汇总可以一起使用
例子:
SELECT Sub1.login AS User_name, Sub1.article AS Activity, Sub1.p_article AS `Activity id`, Sub1.tottime AS `Totaltime(worker)`, Sub2.tottime AS `Totaltime(company)`
FROM (SELECT u.login,a.article, p.p_article, (SUM(p.p_going) + SUM(p.p_leaving) + SUM(p.p_working)) AS tottime
FROM pos p
INNER JOIN users u ON u.login = p.p_login
INNER JOIN articles a ON p.p_article = a.id
WHERE REPLACE( u.login, '.', '_' ) = 'users_name'
AND p.p_datum >= '2013-04-09'
AND p.p_datum <= '2013-04-16'
GROUP BY a.article) Sub1
INNER JOIN
(SELECT a.article, p.p_article, (SUM(p.p_going) + SUM(p.p_leaving) + SUM(p.p_working)) AS tottime
FROM pos p
INNER JOIN articles a ON p.p_article = a.id
WHERE p.p_datum >= '2013-04-09'
AND p.p_datum <= '2013-04-16'
GROUP BY a.article) Sub2
ON Sub1.p_article = Sub2.p_article;
mysql基础-查询语句select使用
1.查询不重复记录
select distinct deptno from emp;
2.条件查询
select * from where deptno=1;
select * from where deptno=1 and sal<2000;
3.排序和限制
1>常用取出按照某个字段进行排序后的记录结果,用关键字order by.
desc 降序,asc 升序,默认是升序
select * from emp order by sal;
select * from emp order by sal desc;
2>对于排序后相同的字段进行再次排序
select * from emp order by sal, deptno desc;
3>对于排序后的记录只显示一部分使用limit
select * from tbname......[limit 偏移量,记录行数]
例子:
select * from emp order by sal limit 3;
select * from emp order by sal limit 2,3;从第三条开始
备注:
默认起始偏移量为0,只写记录行数就行
4.聚合
聚合一般用于数据统计
语法:
select [field1,field2..]fun_name
from tbname
[where where_conditon]
[group by field1,field2..[with rollup]]
[having where_condition]
参数说明:
fun_name 表示要做的聚合操作,也就是聚合函数,常用的有sum(求和)\count(*)(记录数)\max(最大值)\min(最小值).
group by 关键字表示和聚合的字段,比如按照部门分类统计员工数量,group by后就写部门
with rollup 表示对分类聚合后的结果进行再汇总,记录是上面所有记录的总和。
having 表示对分类后的结果进行条件过滤
备注:
having对聚合后的结果进行过滤,where是在聚合前先进行过滤
有必要的话可以先where后进行聚合操作可以提高效率
例子:
1>统计公司中的总人数
select count(1) as c from emp;
2>统计各个部门的人数
select deptno,count(1) from emp group by deptno;
3>既要统计各部门人数,又要统计总人数
select deptno,count(1) from emp group by deptno with rollup;
4>统计人数大于1的部门
select deptno,count(1) from emp group by deptno having count(1)>1;
5>统计公司所有员工的薪水总额\最高和最低
select sum(sal),max(sal),min(sal) from emp;
6>寻找雇员工数超过两个的部门的最高薪水和最低薪水
select bumen,max(xinshui),min(xinshui) from yuangong
group by bumen
having count(*)>2 //count(*表示汇总后各部门的人数-总记录数,因为count(*)条件在having后)
order by bumen;
7>寻找雇员平均工资大于3000的部门的最高和最低薪水
select bumen,max(xinshui),min(xinshui) from yuangong
group by bumen
having avg(xinshui)>3000
order by bumen;
8>使用GROUP_CONCAT()函数可以很好的把分组情况表示出来。
例子:
显示所有部门员工的名字,按部门分组显示
select bumen,group_concat(name) form yuangong group by bumen;
9>各部门的男女的数量
select bumen,sex,count(*) from yuangogn group by bumen,sex;
10>各部门的年龄大于25的男女数量
select bumen,sex,count(*) from yuangong where age>25 group by bumen,sex;
11>年龄大于25,各部门的男女的数量总和大于10 的男女数量
select bumen,sex,count(*) from yuangong where age>25 group by bumen,sex having sum(*)>10;
12>求每个部门的平均薪资
select user_id,round(avg(ifnull(sc_id,0)),2) as avg from sc group by user_id;
5.表连接
内连接: 只连接匹配的行
左外连接: 包含左边表的全部行(不管右边的表中是否存在与它们匹配的行),以及右边表中全部匹配的行
右外连接: 包含右边表的全部行(不管左边的表中是否存在与它们匹配的行),以及左边表中全部匹配的行
全外连接: 包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行。
交叉连接: 生成笛卡尔积-它不使用任何匹配或者选取条件,而是直接将一个数据源中的每个行与另一个数据源的每个行都一一匹配
效率问题:
1.inner join比left join快
注:inner join 内连接等价于下面的sql: SELECT A.name, B.address FROM A, B WHERE A.id = B.A_id所以一般要用一般的连接就可以了.
2.连接字段建索引
__________________________________________________________________
1>内连接:仅选出两张表互相匹配的记录,A,B表中至少有1个匹配时,才返回行。两表的交集
例子:
如果两张表中对应的字段一定有对应使用内连接
select ename,deptname from emp,dept where emp.deptno=dept.deptno;
select A.name,B.address from A inner join B on A.id = B.A_id
__________________________________________________________________
2>左连接:包含所有左边表中的记录甚至是右边表中没有和它匹配的记录
select ename,deptname from emp left join dept on emp.deptno=dept.deptno;
__________________________________________________________________
3>右连接:包含所有的右边表中的记录甚至是左边表中没有和他匹配的记录,和左连接类似可以互相转化
select ename,deptname from dept right join emp on emp.deptno=dept.deptno;
备注:
链接都是以on作为条件的
6.子查询
某些情况下需要查询的时候,需要的条件是另一个select语句的结果,这时候用子查询.
用于子查询的关键字包括(in|not in|=|!=|exists|not exists)等.
例子:
1>in 条件记录为多个
select * from emp where deptno in(select deptno from dept)
2.= 条件记录为1
select * from emp where deptno=(select deptno from dept where id=1);
备注:
某些情况下表连接可以替代子查询用于优化
7.记录联合
有时候需要将两张表的记录查询出来之后合并到一起显示
union 合并到一起并且进行一次distinct去重
union all 合并到一起显示
select deptno from emp
union
select deptno from dept;
8.子查询和表连接还有汇总可以一起使用
例子:
SELECT Sub1.login AS User_name, Sub1.article AS Activity, Sub1.p_article AS `Activity id`, Sub1.tottime AS `Totaltime(worker)`, Sub2.tottime AS `Totaltime(company)`
FROM (SELECT u.login,a.article, p.p_article, (SUM(p.p_going) + SUM(p.p_leaving) + SUM(p.p_working)) AS tottime
FROM pos p
INNER JOIN users u ON u.login = p.p_login
INNER JOIN articles a ON p.p_article = a.id
WHERE REPLACE( u.login, '.', '_' ) = 'users_name'
AND p.p_datum >= '2013-04-09'
AND p.p_datum <= '2013-04-16'
GROUP BY a.article) Sub1
INNER JOIN
(SELECT a.article, p.p_article, (SUM(p.p_going) + SUM(p.p_leaving) + SUM(p.p_working)) AS tottime
FROM pos p
INNER JOIN articles a ON p.p_article = a.id
WHERE p.p_datum >= '2013-04-09'
AND p.p_datum <= '2013-04-16'
GROUP BY a.article) Sub2
ON Sub1.p_article = Sub2.p_article;