1.分组与过滤
where 过滤条件group by 字段1,字段2,...*/#求各部门中最高的薪水SELECT department_id, MAX(salary)FROM employeesWHERE department_id IS NOT NULLGROUP BY department_id;#求各部门中最高的薪水,按照最高薪水排序SELECT department_id, MAX(salary)FROM employeesWHERE department_id IS NOT NULLGROUP BY department_idORDER BY MAX(salary);#求各部门中各工种的平均薪水SELECT department_id,job_id,AVG(salary)FROM employeesWHERE department_id IS NOT NULLGROUP 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 employeesWHERE department_id IN(10,20,30)GROUP BY department_idHAVING AVG(salary)>4200;#方式二:SELECT department_id, AVG(salary)FROM employeesGROUP BY department_idHAVING 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 salaryFROM employeesWHERE last_name='Abel'; #11000SELECT last_name,salaryFROM employeesWHERE salary > 11000;#方式二:自连接SELECT e.`last_name`,e.`salary`FROM employees e JOIN employees e2ON e.`salary`>e2.`salary` AND e2.`last_name`='Abel';#方式三:子查询SELECT last_name,salaryFROM employeesWHERE salary > (SELECT salaryFROM employeesWHERE last_name='Abel')#题目:返回job_id与141号员工相同,salary比143号员工多的员工# 姓名,job_id 和工资#方式一:#1.先查出141号员工的job_idSELECT job_idFROM employeesWHERE employee_id=141;#ST_CLERK#2.再查出143号员工的薪水SELECT salaryFROM employeesWHERE employee_id=143;#2600#3.再查出结果SELECT last_name,job_id,salaryFROM employeesWHERE job_id='ST_CLERK' AND salary>2600;#方式二SELECT last_name,job_id,salaryFROM employeesWHERE job_id=(SELECT job_idFROM employeesWHERE employee_id=141) AND salary>(SELECT salaryFROM employeesWHERE employee_id=143);#题目:返回公司工资最少的员工的last_name,job_id和salary#方式一:#1.先获取最低工资SELECT MIN(salary)FROM employees; #2100#2.再根据最低工资查出相应信息SELECT last_name,job_id,salaryFROM employeesWHERE salary=2100;#方式二:SELECT last_name,job_id,salaryFROM employeesWHERE salary=(SELECT MIN(salary)FROM employees);#题目:查询最低工资大于50号部门最低工资的部门id和其最低工资SELECT department_id,MIN(salary)FROM employeesWHERE department_id IS NOT NULLGROUP BY department_idHAVING MIN(salary) > (#50号部门最低薪水SELECT MIN(salary)FROM employeesWHERE department_id=50);#多行子查询#题目:返回其它部门中比job_id为‘IT_PROG’部门任一工资低的员工的员# 工号、姓名、job_id 以及salarySELECT employee_id,last_name,job_id,salaryFROM employeesWHERE salary <ANY(#job_id为IT的薪水SELECT DISTINCT salaryFROM employeesWHERE job_id='IT_PROG') AND job_id <> 'IT_PROG';#题目:返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工# 的员工号、姓名、job_id 以及salarySELECT employee_id,last_name,job_id,salaryFROM employeesWHERE salary <ALL(#job_id为IT的薪水SELECT DISTINCT salaryFROM employeesWHERE 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 emp3SELECT employee_id,first_nameFROM 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
