赞
踩
在上篇文章中我总结了基本的增删查改语法,本篇文章我来叙述一下基本查询的后半部分
单个查询的语法上篇文章已经了解了,下面开始看看两个查询语句复合使用的场景
语法:
INSERT INTO table_name [(column [, column ...])] SELECT ...
案例:删除表中的重复记录,即重复的数据只能有一份
---- 创建带有重复数据的数据表 mysql> CREATE TABLE duplicate_table (id int, name varchar(20)); -- 插入测试数据 mysql> INSERT INTO duplicate_table VALUES -> (100, 'aaa'), -> (100, 'aaa'), -> (200, 'bbb'), -> (200, 'bbb'), -> (200, 'bbb'), -> (300, 'ccc'); --查询表中信息 mysql> select * from duplicate_table; +------+------+ | id | name | +------+------+ | 100 | aaa | | 100 | aaa | | 200 | bbb | | 200 | bbb | | 200 | bbb | | 300 | ccc | +------+------+ --创建另一张表 mysql> create table no_duplicate_table like duplicate_table; --原表去重后的数据插入到新表中 mysql> insert into no_duplicate_table select distinct *from duplicate_table; --查询新表信息 mysql> select * from no_duplicate_table; +------+------+ | id | name | +------+------+ | 100 | aaa | | 200 | bbb | | 300 | ccc | +------+------+ --修改表名,实现原子的去重 mysql> rename table duplicate_table to old_duplicate_table,no_duplicate_table TO duplicate_table; mysql> select * from duplicate_table; +------+------+ | id | name | +------+------+ | 100 | aaa | | 200 | bbb | | 300 | ccc | +------+------+
这里通过rename修改表名是为了等表的操作结束后,统一放入,更新,生效,节省时间
MySQL中的聚合函数常用于对数据进行计算和统计,以下是几种常见的聚合函数
函数 | 说明 |
---|---|
COUNT([DISTINCT] expr) | 返回查询到的数据的数量 |
SUM([DISTINCT] expr) | 返回查询到的数据的 总和,不是数字没有意义 |
AVG([DISTINCT] expr) | 返回查询到的数据的 平均值,不是数字没有意义 |
MAX([DISTINCT] expr) | 返回查询到的数据的 最大值,不是数字没有意义 |
MIN([DISTINCT] expr) | 返回查询到的数据的 最小值,不是数字没有意义 |
统计班级共有多少同学
mysql> select * from stu; +----+-----------+---------+------+---------+ | id | name | chinese | math | english | +----+-----------+---------+------+---------+ | 1 | 唐三藏 | 134 | 98 | 56 | | 3 | 猪悟能 | 176 | 98 | 90 | | 4 | 曹孟德 | 140 | 90 | 67 | | 5 | 刘玄德 | 110 | 115 | 45 | | 6 | 孙权 | 140 | 73 | 78 | | 7 | 宋公明 | 150 | 95 | 30 | +----+-----------+---------+------+---------+ --统计行数 mysql> select count(1) from stu; mysql> select count(*) from stu; +----------+ | count(1) | +----------+ | 6 | +----------+
统计班级的数学成绩有多少个(去重)
mysql> select math from stu; +------+ | math | +------+ | 98 | | 98 | | 90 | | 115 | | 73 | | 95 | +------+ --正确的去重:先去重后聚合 mysql> select count(distinct math) from stu; +----------------------+ | count(distinct math) | +----------------------+ | 5 | +----------------------+ --错误的去重:先聚合后去重 mysql> select distinct count( math) from stu; +--------------+ | count( math) | +--------------+ | 6 | +--------------+
mysql> select sum(math) from stu;
+-----------+
| sum(math) |
+-----------+
| 569 |
+-----------+
1.统计数学成绩总分
2.统计数学成绩的平均分
3.统计英语成绩不及格的人数
4.返回英语最高分
5.返回 > 70 分以上的数学最低分
--1 mysql> select sum(math) from stu; +-----------+ | sum(math) | +-----------+ | 569 | +-----------+ 1 row in set (0.00 sec) -----2 mysql> select avg(math) from stu; +-------------------+ | avg(math) | +-------------------+ | 94.83333333333333 | +-------------------+ mysql> select sum(math)/count(*) from stu; +--------------------+ | sum(math)/count(*) | +--------------------+ | 94.83333333333333 | +--------------------+ -----3 mysql> select count(*) from stu where english<60; +----------+ | count(*) | +----------+ | 3 | +----------+ --4 mysql> select max(english) from stu; +--------------+ | max(english) | +--------------+ | 90 | +--------------+ --5 mysql> select min(math) from stu where math>70; +-----------+ | min(math) | +-----------+ | 73 | +-----------+
分组的目的是为了进行分组之后,方便进行聚合统计
在select中使用group by 子句可以对指定列进行分组查询
select column1, column2, .. from table group by column;
结合案列探讨
EMP员工表
DEPT部门表
SALGRADE工资等级表
显示每个部门的平均工资和最高工资
group by ‘列名’:分组是以同一列不同行数据来进行分组的;分组过后,每组内的【分组列名如deptno】,一定是一样的,可以被聚合压缩
mysql> select deptno,max(sal) 最高,avg(sal)平均 from emp group by deptno;
+--------+---------+-------------+
| deptno | 最高 | 平均 |
+--------+---------+-------------+
| 10 | 5000.00 | 2916.666667 |
| 20 | 3000.00 | 2175.000000 |
| 30 | 2850.00 | 1566.666667 |
+--------+---------+-------------+
显示每个部门的每种岗位的平均工资和最低工资
mysql> select deptno,job,avg(sal)平均,min(sal) 最低 from emp group by deptno,job;
+--------+-----------+-------------+---------+
| deptno | job | 平均 | 最低 |
+--------+-----------+-------------+---------+
| 10 | CLERK | 1300.000000 | 1300.00 |
| 10 | MANAGER | 2450.000000 | 2450.00 |
| 10 | PRESIDENT | 5000.000000 | 5000.00 |
| 20 | ANALYST | 3000.000000 | 3000.00 |
| 20 | CLERK | 950.000000 | 800.00 |
| 20 | MANAGER | 2975.000000 | 2975.00 |
| 30 | CLERK | 950.000000 | 950.00 |
| 30 | MANAGER | 2850.000000 | 2850.00 |
| 30 | SALESMAN | 1400.000000 | 1250.00 |
+--------+-----------+-------------+---------+
注意事项:在group by之后出现的字段是可以在select 之后出现的,还有聚合函数,其余的不一定【select ename,deptno,job,avg(sal)平均,min(sal) 最低 from emp group by deptno,job;】就会报错,因为ename不是聚合条件
having一般搭配group by使用
显示平均工资低于2000的部门和它的平均工资
--这里先进行聚合压缩统计,having再开始条件筛选
mysql> select deptno,avg(sal) deptavg from emp group by deptno having deptavg<2000;
+--------+-------------+
| deptno | deptavg |
+--------+-------------+
| 30 | 1566.666667 |
+--------+-------------+
除SMITH外,显示平均工资低于2000的每个部门的每种岗位的和它的平均工资
SQL查询中各个关键字的执行先后顺序 :from > on> join > where > group by > with > having > select>distinct > order by > limit
insert into actor values(1,"PENELOPE","GUINESS","2006-02-15 12:34:33"),(2,"NICK","WAHLBERG","2006-02-15 12:34:33");
select distinct salary from salaries order by salary desc;
select * from employees order by hire_date desc limit 1;
select * from employees
where hire_date=(
select distinct hire_date from employees order by hire_date desc limit 2,1
);
select emp_no,count(*) t from salaries group by emp_no having t>15;
select title,count(title) t from titles group by title having t>=2;
select email from Person group by email having count(email)>1;
select name,population,area from World where area>=3000000 or population>=25000000;
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
SET N = N - 1;
RETURN (
select distinct(Salary) as getNthHighestSalary
from Employee
GROUP BY Salary
ORDER BY Salary DESC
limit 1 offset N
);
END
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。