1.分组与过滤
where 过滤条件
group by 字段1,字段2,...
*/
#求各部门中最高的薪水
SELECT department_id, MAX(salary)
FROM employees
WHERE department_id IS NOT NULL
GROUP BY department_id;
#求各部门中最高的薪水,按照最高薪水排序
SELECT department_id, MAX(salary)
FROM employees
WHERE department_id IS NOT NULL
GROUP BY department_id
ORDER BY MAX(salary);
#求各部门中各工种的平均薪水
SELECT department_id,job_id,AVG(salary)
FROM employees
WHERE department_id IS NOT NULL
GROUP BY department_id,job_id;
# 求10,20,30号部门的平均薪水,并要求平均薪水>4200
/*
where和having的区别?
1.where后面不能出现组函数,having后面可以出现组函数
2.where在group by的前面,having在group by的后面
*/
#方式一:效率更高
SELECT department_id, AVG(salary)
FROM employees
WHERE department_id IN(10,20,30)
GROUP BY department_id
HAVING AVG(salary)>4200;
#方式二:
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id
HAVING AVG(salary)>4200 AND department_id IN(10,20,30);
GROUP BY
HAVING
注意2:一旦select后面出现组函数(聚合函数,多行函数)就不能再出现其它字段。
除非该字段也出现在group by的后面。
where和having的区别?
1.where后面不能出现组函数,having后面可以出现组函数
2.where在group by的前面,having在group by的后面。
3.一般先用where过滤完分组字段再用having过滤别的字段
2.子查询
/*
子查询:在一个查询语句a中可以再嵌套一个查询语句b,那么b语句叫作子查询(内查询)
a语句叫作主查询(外查询)
子查询分类 :单行子查询 vs 多行子查询
单行子查询 :子查询的结果只有一条
多行子查询 :子查询的结果有多条
单行子查询使用的运算符 := <> > >= < <=
多行子查询使用的运算符 :in any all
查询语句在执行时会先执行子查询再执行主查询。
*/
#案例 :谁的工资比 Abel 高?
#方式一:①先查出Abel工资 ②再查出比Abel高的工资
SELECT salary
FROM employees
WHERE last_name='Abel'; #11000
SELECT last_name,salary
FROM employees
WHERE salary > 11000;
#方式二:自连接
SELECT e.`last_name`,e.`salary`
FROM employees e JOIN employees e2
ON e.`salary`>e2.`salary` AND e2.`last_name`='Abel';
#方式三:子查询
SELECT last_name,salary
FROM employees
WHERE salary > (
SELECT salary
FROM employees
WHERE last_name='Abel'
)
#题目:返回job_id与141号员工相同,salary比143号员工多的员工
# 姓名,job_id 和工资
#方式一:
#1.先查出141号员工的job_id
SELECT job_id
FROM employees
WHERE employee_id=141;#ST_CLERK
#2.再查出143号员工的薪水
SELECT salary
FROM employees
WHERE employee_id=143;#2600
#3.再查出结果
SELECT last_name,job_id,salary
FROM employees
WHERE job_id='ST_CLERK' AND salary>2600;
#方式二
SELECT last_name,job_id,salary
FROM employees
WHERE job_id=(
SELECT job_id
FROM employees
WHERE employee_id=141
) AND salary>(
SELECT salary
FROM employees
WHERE employee_id=143
);
#题目:返回公司工资最少的员工的last_name,job_id和salary
#方式一:
#1.先获取最低工资
SELECT MIN(salary)
FROM employees; #2100
#2.再根据最低工资查出相应信息
SELECT last_name,job_id,salary
FROM employees
WHERE salary=2100;
#方式二:
SELECT last_name,job_id,salary
FROM employees
WHERE salary=(
SELECT MIN(salary)
FROM employees
);
#题目:查询最低工资大于50号部门最低工资的部门id和其最低工资
SELECT department_id,MIN(salary)
FROM employees
WHERE department_id IS NOT NULL
GROUP BY department_id
HAVING MIN(salary) > (
#50号部门最低薪水
SELECT MIN(salary)
FROM employees
WHERE department_id=50
);
#多行子查询
#题目:返回其它部门中比job_id为‘IT_PROG’部门任一工资低的员工的员
# 工号、姓名、job_id 以及salary
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary <ANY(
#job_id为IT的薪水
SELECT DISTINCT salary
FROM employees
WHERE job_id='IT_PROG'
) AND job_id <> 'IT_PROG';
#题目:返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工
# 的员工号、姓名、job_id 以及salary
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary <ALL(
#job_id为IT的薪水
SELECT DISTINCT salary
FROM employees
WHERE job_id='IT_PROG'
) AND job_id <> 'IT_PROG';
子查询:在一个查询语句a中可以再嵌套一个查询语句b,那么b语句叫作子查询(内查询)
a语句叫作主查询(外查询)
子查询分类 :单行子查询 vs 多行子查询
单行子查询 :子查询的结果只有一条
多行子查询 :子查询的结果有多条
单行子查询使用的运算符 := <> > >= < <=
多行子查询使用的运算符 :in(等值) any all
—All:对所有数据都满足条件,整个条件才成立,例如:5大于所有返回的id
—Any:只要有一条数据满足条件,整个条件成立,例如:3大于1,2
查询语句在执行时会先执行子查询再执行主查询。
3.库操作
#笛卡尔集的错误。
#导致的原因:缺少连接条件或连接条件错误
SELECT e.`first_name`,d.`department_name`
FROM employees e,departments d;
#查看所有的库
SHOW DATABASES;
#选库
USE 库名;
#创建库:create database [if not exists] 库名 [character set '编码集']
CREATE DATABASE db;
#if not exists :如果库不存在则创建,存在则不创建。如果没有该字段库存在则报错。
CREATE DATABASE IF NOT EXISTS db;
#character set '编码集' :指定库的编码集
CREATE DATABASE db2 CHARACTER SET 'gbk';
#查看库的信息
SHOW CREATE DATABASE db2;
#修改库的编码集
ALTER DATABASE db CHARACTER SET 'utf8';
#删除库:drop database [if exists] 库名
#if exists :库存在则删除不存在则不删,如果没有该字段库不存在则报错。
DROP DATABASE IF EXISTS db;
SHOW USE
CREAT DATABASE IF NOT EXISTS
CREAT DATABASE CHARACTER SET’GBK’
SHOW CREATE DATABASE
ALTER DATABASE CHARACTER SET’GBK’
DROP DATABASE IF EXISTS
4.表操作
#查看表
SHOW TABLES;
#查看表的信息
SHOW CREATE TABLE emp2;
#查看表结构
DESC emp;
#创建表
#方式一:白手起家
#注意:表的默认编码集和库的编码集相同。
CREATE TABLE emp(
id INT,
ename VARCHAR(20) #注意:最后一个字段没有","号
)
#IF NOT EXISTS :表不存在则创建,存在则不创建。如果没有该字段表存在则报错。
CREATE TABLE IF NOT EXISTS emp2(
id INT,
ename VARCHAR(20) #注意:最后一个字段没有","号
)CHARACTER SET 'utf8';
#方式二:基于查询的结果创建一张新表
CREATE TABLE emp3
SELECT employee_id,first_name
FROM myemployees.`employees`; #夸库读表 :库名.表名
#方式三:根据现有表的结构创建一张新表(没有内容)
CREATE TABLE emp4 LIKE myemployees.employees;
#删除表
#IF EXISTS : 如果表存在则删除不存在则不删,如果没有该字段表不存在则报错。
DROP TABLE IF EXISTS emp4;
SHOW TABLES
SHOW CREATE TABLE
DESC
#创建表
方式一:白手起家
注意:表的默认编码集和库的编码集相同。
CREATE TABLE emp(
id INT,
ename VARCHAR(20) #注意:最后一个字段没有”,”号
)
IF NOT EXISTS; :表不存在则创建,存在则不创建。如果没有该字段表存在则报错。
CHARACTER SET ‘utf8’;
方式二:基于查询的结果创建一张新表
CREATE TABLE emp3
SELECT employee_id,first_name
FROM myemployees.employees
; #夸库读表 :库名.表名
方式三:根据现有表的结构创建一张新表(没有内容)
CREATE TABLE emp4 LIKE myemployees.employees;
删除表
#IF EXISTS : 如果表存在则删除不存在则不删,如果没有该字段表不存在则报错。
DROP TABLE IF EXISTS emp4;
5.表字段操作2
/*
对表中的字段进行添加,修改,删除的操作
alter table 表名 add/change/modify/drop .......
*/
#添加字段
ALTER TABLE emp ADD eage INT;
#修改字段的名字:ALTER TABLE 表名 CHANGE 原字段名 新字段名 字段的类型;
ALTER TABLE emp CHANGE eage age INT;
#修改字段的类型:很危险的一件事
ALTER TABLE emp MODIFY age INT;
#删除字段
ALTER TABLE emp DROP age;
#修改表的名字
ALTER TABLE emp RENAME TO employee;
#清空表中的内容
TRUNCATE TABLE emp3;
ALTER TABLE ADD
ALTER TABLE CHANGE
ALTER TABLE MODIFY
ALTER TABLE DROP
ALTER TABLE RANAME TO
TRUNCATE TABLE