Mysql基础练习

一、MySQL

mysql 常用命令

  1. show databases; 展示所有数据库
  2. use database_name ;
  3. show tables;
  4. show tables from database_name;
  5. select database() ;目前数据库
  6. create table stuinfo(id int, name varchar(20));
  7. desc stuinfo; 查看表结构
  8. 增删改查 insert delete update select

sql语法规范

  1. 不区分大小写,建议关键字大写,表名列名小写
  2. 每条分号结尾
  3. 命令可以缩进换行
  4. 单行 注释 两种 – # 多行 /**/

sql语言分类

  1. DQL:Data Query Lan :查
  2. DML: Data Manipulation Lan :增删改
  3. DDL: Data Define Lan :库表的定义 约束
  4. TCL: Transaction Control Lan :事务控制处理
  5. DCL: Data Control Lan :数据库权限控制
  6. 视图
  7. 存储过程与函数
  8. 流程控制

myemploee表

  • 分类存储 减少冗余 (第三范式 一个表内只有其他表的主键,不包含其他表的非主属性,即外键的使用。使用其他表的主键作为外键 )
  1. employees表
    在这里插入图片描述
  2. 部门表
    在这里插入图片描述
  3. 位置
    在这里插入图片描述
  4. 工种
    在这里插入图片描述

查询语句 (查询占80%)

1.基础查询

  1. 查询列表可以是:表中的字段、常量、表达式、函数
  2. 查询的结果是一个虚拟表格
#1.查询单个字段
#2.查询表中的多个字段
#3.查询所有的字段
select * from employee;--这个顺序是固定的
select `last_name`,`email`,.... from employee;--可以排顺序 `  `符号可以加可以不加 , 强调是个字段名 ,与关键字区分 ,提高可读性

#4.查询常量值
select 100;  -- 直接获得常量值
select '聂捷'; --字符串常量
#5.查询表达式
select 100%98;
#6.查询函数
select VERSION(); --可以查询自己创建或者数据库自带的函数
#7.起别名  (为字段名起别名  如改sex 为性别)
--作用 一是便于理解  二是连接查询有重名可以用于区分
select sex AS 性别 from employees;
select sex 性别 ,last_name 姓  from  employees;
--当别名有特殊符号时要加双引号
select salary AS "out put" From empoyees;
#8.去重
--查询所有的部门编号
select DISTINCT department_id from employees;
#9. +号的作用 
--+ 号在sql中只作为运算符 '123'+23 会转换为数字计算
--转换不成功则将字符串转换为0
select ‘john’+90;--结果为o
--一方为null全为null
select null+10 ;--结果为null;
#10.字符串拼接 concat函数
select Concat('a','b','c') as 结果;
select Concat(last_name,first_name) as 姓名 from employees;
#11. 

条件查询

-- 一、条件查询
-- 1.按条件表达式筛选
#员工工资大于12000的员工信息
SELECT 
		* 
FROM
		employees
WHERE
		salary>12000;
#查询部门编号不等于90 的员工和部门编号
SELECT 
		last_name,
		department_id
FROM
		employees
WHERE
		department_id<>90; -- <>为不等于

-- 2、按逻辑表达式筛选 and or not  &&  || !
	-- &&两个表达式都为true  这个是java的长路与  能判断时只运行左边  即当左边为false右边不计算
	#查询工资在10000到20000之间的员工名以及奖金
	SELECT first_name,salary,commission_pct from employees where salary>=10000 AND salary<=20000;
	#查询部门编号不是在90到110之间的,或者工资高于15000的员工信息
	SELECT * from employees where not(department_id>=90 and department_id<=110 )or salary>15000;
-- 3、模糊查询
-- like  BETWEEN and    in  is null  is not NULL
# like 和通配符一起使用  
			-- % 任意多个字符 ,包含0个字符
			-- _  下划线表示一个字符
# 查询员工名中包含字母a的员工信息
SELECT * FROM employees WHERE last_name like '%a%'; -- 字符型用单引号  %为通配符
select * from employees where last_name like '____a%'; -- _ 占一个字符

# 查询员工名第二个字符为_ 的员工名
SELECT last_name from  employees where last_name like '_\_%'; -- \为转义字符
select last_name from employees WHERE last_name like '_$_%' ESCAPE '$';-- 定义$为转义字符
#查询员工编号 在100到120之间的员工信息
SELECT * from  employees WHERE employee_id BETWEEN 100 and 120;-- ba 包含临界值
#查询员工的工种编号是 IT_PPOT AD_VP   使用in匹配 ()里的列表
select last_name,job_id FROM employees WHERE job_id in(IT_PROT,AD_VP,AD_PRES); -- in关键字匹配字符
-- in列表的类型必须兼容  不可以使用通配符  like 才可以
#查询没有奖金的员工和奖金率
select last_name,commission_pct from employees WHERE commission_pct is null; -- 判断null要用这个
SELECT last_name,commission_pct from employees WHERE commission_pct is not null;
#安全等于   <=>  可以判断null 和 普通值
select last_name,commission_pct from employees where  commission_pct <=> null;
select last_name,salary from employees WHERE salary <=> 12000;
select last_name,department_id,salary*12*(1+IFNULL(commission_pct,0)) as 年薪
				from employees;
-- 阶段练习
select * from employees WHERE job_id <> 'IT' and salary = 12000;
desc departments;
select distinct location_id from departments ;
-- 以下存在null值  结果是不一样的  后面一句匹配不到null值
SELECT * from employees ;
select * from employees WHERE commission_pct like '%%' and last_name like'%%';

排序查询

-- 二、排序查询
-- 语法  select 查询列表  from 表 where 条件 order by 排序列表 asc desc 
-- asc  升序  (默认)  desc 降序
# 查询员工信息,要求工资从高到低
SELECT * from employees  order by salary asc;
#查询部门编号>=90的员工信息  按入职先后排序
select * from employees WHERE department_id>=90 ORDER BY hiredate DESC;
# 按表达式排序
select * ,salary*12*(1+commission_pct) as 年薪 from employees ORDER BY 年薪 desc; 
# 按名字长度排序
select LENGTH(last_name) 字节长度,last_name FROM employees ORDER BY 字节长度 desc;
# 多个字段排序  按第一个字段  重复的按第二个字段
select * from employees ORDER BY salary asc,last_name desc;  

--  sql执行顺序  from -> WHERE -> select ->order by  先锁定表 再筛选行 再筛选列 再排序
-- 练习
# 选择工资不在8000到17000 的员工的姓名和工资 再按照部门编号升序排列
select last_name,salary ,department_id from employees WHERE salary < 8000 or salary>17000 order by department_id asc;
-- 也可以使用 not BETWEEN and 
select last_name,department_id,salary from employees WHERE salary not BETWEEN 8000 and 15000 ORDER BY salary desc ;
# 查询员工名字里包含‘a'的员工的薪水 并且按降序排列
select last_name ,salary from employees WHERE last_name like '%a%' ORDER BY salary desc ;
select email ,LENGTH(email) 邮件长度 from employees  ORDER BY LENGTH(email);

常见函数(单行)

-- 三、常见函数的使用
-- 函数 把功能封装在方法体内 对外暴露封装细节 直接调用 select 函数名(实参列表) from 表
--  1.单行函数 Concat , length , isfull等
--  2.聚合函数(分组函数,统计函数)


-- 练习
-- 查询邮箱中的含e的员工信息 按字节降序 部门号升序
select length(email) 邮箱长度 ,employees.* from employees where email like '%e%' order by length(email) desc,department_id asc;

-- 常见函数 select  函数名(实参列表) 【from 表】
	-- 知道  1.函数的名字  2.函数的功能

-- 分为单行函数和分组函数   分组函数又叫聚合函数  统计函数 分组函数


-- 一、字符函数
	-- 1. length  
	select length('张三分');
	show variables like '%char%';
	-- 2. concat 拼接字符串
	select Concat("名字",last_name) from employees;
	-- 3.大小写转换 LOWER UPPER  
	select LOWER(first_name) from employees;
	-- 4.substr 、substring  有重载
	select substr('李莫愁爱上陆展元',6); out_put; -- mysql基1
	select substr("我爱刘玉琴",3,5);
			-- 姓名中首字符大写  其他字符小写 再用_ 拼接显示
		select concat(Upper(substr(last_name,1,1)),'_',lower(substr(last_name,2))) from employees;
	--  5.instr  返回子串第一次出现的索引 没有返回0
	select instr('杨不悔爱上杨过杨过','杨过') out_put ;
	--  6.去字符串前后的 空格 或者指定字符串
	select trim("      张翠 仙   ") as output;
	-- 7.lpad 用指定的字符左填充指定的长度
	select lpad('段素素',10,'*')as out_put;
	-- 8.rpad 右填充
	select rpad ('刘玉琴',10,'爱我') as love;
	-- replace 替换
	select replace('我爱罗','罗','刘玉琴')as out_put;
-- 日期函数
	-- 1. now 返回当前系统的日期时间
	select now();
	-- 2.curdate();返回当前日期
	select curdate();
	-- 3.curtime() 返回当前时间
	select curtime();
	-- 4.     获取指定的部分 加year() Monthname() 获取月份名
						-- second minite
	select monthname(now());
	select day(curdate());
	select yearweek(now());
	select minute(now());
	-- 5.str_to_date 将日期格式的字符串转换成指定的日期
		-- %Y %y  四位 两位的年份
		-- %i 分钟  %m 01月 %c 1月  %d 日 %H 24小时制 %h12小时制 %s 秒
	select str_to_date('1998-3-2','%Y-%c-%d') AS OUT_PUT;
			-- 查询入职日期为1992-4-3的员工信息
			select * from employees where hiredate = STR_TO_DATE('4--3 1992','%m--%d %Y');
			select * from employees where hiredate > STR_TO_DATE('1992-4-2','%Y-%m-%d');
	-- 6.date_format 函数 转换data为 字符串
			-- 转换date  为 xx年xx月
	select last_name,date_format(hiredate,'%Y年%m月%d日')入职日期 from employees;


-- 数学函数
	-- 1.round 四舍五入
	select round(1.45);
	select round(-1.55);
	select round(1.678,2) -- 保留两位小数
	-- 2.ceil 向上取整 返回大于这个数的最小整数
	select ceil(-1.34);
	-- 3.floor 向下取整
	select floor(-1.2354);
	-- 4.truncate 截断  取几位数  后面直接截断
	select truncate(1.343566,3);
	-- mod 取余
	select mod(-10,3);  -- 被除数
	select mod(10,-3);  
	select 10%3;
-- 其他函数 
	-- VERSION() 
	select  version();
	-- datebases() 所有数据库  数据库
	select  database();
	-- user()
	select user();


-- 流程控制函数
	-- 1. if 函数
	select if(6>3,'不大' ,'大于');
	select last_name, if(commission_pct is null ,'没奖金啊','哈哈有奖金啊') from employees;\
	-- 2.case 函数 类似 switch case语句  等值判断
			-- case 要判断的字段或者表达式  when 常量 then 要显示的语句1;else 要显示的;end;
	select salary  原工资,department_id,
		case department_id 
		when 90 then salary*1.6
		when 60 then salary*1.4
		ELSE salary
		end as 新工资 from employees;
	-- 直接用case作为语句  相当于 java的多重if  判断区间
	select salary ,
	case 
	when salary>10000 then '月薪过万'
	when salary<10000 then '月薪未过万'
end as 是否过万 from employees;


 常见函数总结
	/*  字符串函数
			日期函数
			数字函数
			其他函数
			流程控制函数
			*/
-- 练习1 显示系统时间
	select curdate();
	select now();
	select DATE_FORMAT(now(),'%m-%d-%i-%s')
-- 练习2 查询员工号 姓名 工资  以及提高20%的工资 newsalary
	select employee_id,first_name,salary,salary*1.2 newsalary from employees;
-- 练习3 做一个查询 产生
	select last_name ,'earns',salary,'monthly but wants 72000' from employees;
	select concat(last_name,'earn',salary,'monthly but wants 72000') from employees;
-- 练习4 按首字符排序
	select last_name , subStr(last_name,1,1) 首字符 from employees ORDER BY 首字符 asc;	
	select last_name , substr(last_name,length(last_name),length(last_name)) as 尾字符 from employees order by 尾字符 asc ;
-- 练习5 case 语句
	select job_id as job,
		case job_id
		when 'AD_PRES' then '牛逼'
		end
		as 评价 
		from employees;
-- 经常都是 他娘的拼写和 多谢漏写错误  检查符号 拼写  气死老子了

常见函数之聚合函数(统计分组函数)

-- 分组函数  聚合函数  组函数  统计函数 一组值得到一个值
-- 分类  sum avg max min count 
-- 1. 简单函数 sum 
	select sum(salary) from employees;
	select avg(salary) from employees;
	select round(avg(salary),2) from employees;
	select count(salary) from employees;
	select max(salary) 最大工资,min(salary)最小工资 from employees;
-- 2.参数类型支持哪些类型
	-- avg sum 处理数值类型  max min count 可以用在非数值类型
	select sum(last_name)from employees; -- 已经没有意义 处理数值类型 
-- 3.是否忽略null 值  是忽略null值的
		select commission_pct from employees;
		select count(*) ,count(commission_pct) from employees;
		select sum(commission_pct) ,avg(commission_pct),sum(commission_pct)/107,sum(commission_pct)/35
						from employees;
-- 4.和distinct 搭配
	select sum(distinct salary) ,sum(salary) from employees;
	select count(distinct salary) from employees; -- 计算有几种工资
-- 5. count 函数详细
		-- 支持四种重载
			 select count(*) from employees ; # 每行只要有一个不为null就统计
			select count(1) from employees; # 相当于加了一行全为1   统计1的行数
			-- 以上两种效率  myisam 由内核计数器 count(*) 的效率高
									--   innodb 效率差不多 都是统计行数  比count(字段) 效率高
-- 6.和分组函数一同查询的字段有限制  要求是group by 的字段
			select avg(salary) ,employee_id from employees;  -- 这个虽然没报错但是不对
			-- 练习1 查询员工工资的最大值,最小值,平均值,总和
				select max(salary),avg(salary),count(salary)from employees;
			-- 练习2 查询员工表中的最大入职天数和最小入职天数的差值
				select max(hiredate)-min(hiredate) from employees;
				
				-- datediff  -- 求两个日期的差
	·			select datediff(max(hiredate),min(hiredate)) from employees;
			-- 练习员工号为90 的 员工个数
				select count(*) from employees where department_id = 90;
			
				

分组查询

-- 分组查询 group by 


/*
(1) FROM:对FROM子句中的左表<left_table>和右表<right_table>执行笛卡儿积,产生虚拟表VT1;
(2) ON: 对虚拟表VT1进行ON筛选,只有那些符合<join_condition>的行才被插入虚拟表VT2;
(3) JOIN: 如果指定了OUTER JOIN(如LEFT OUTER JOIN、RIGHT OUTER JOIN),那么保留表中未匹配的行作为外部行添加到虚拟表VT2,产生虚拟表VT3。如果FROM子句包含两个以上的表,则对上一个连接生成的结果表VT3和下一个表重复执行步骤1~步骤3,直到处理完所有的表;
(4) WHERE: 对虚拟表VT3应用WHERE过滤条件,只有符合<where_condition>的记录才会被插入虚拟表VT4;
(5) GROUP By: 根据GROUP BY子句中的列,对VT4中的记录进行分组操作,产生VT5;
(6) CUBE|ROllUP: 对VT5进行CUBE或ROLLUP操作,产生表VT6;
(7) HAVING: 对虚拟表VT6应用HAVING过滤器,只有符合<having_condition>的记录才会被插入到VT7;
(8) SELECT: 第二次执行SELECT操作,选择指定的列,插入到虚拟表VT8中;
(9) DISTINCT: 去除重复,产生虚拟表VT9;
(10) ORDER BY: 将虚拟表VT9中的记录按照<order_by_list>进行排序操作,产生虚拟表VT10;
(11) LIMIT: 取出指定街行的记录,产生虚拟表VT11,并返回给查询用户
*/
	-- 1. select 分组函数 ,列 from 表 where 条件 GROUP BY 分组列表,order by 子句
		-- 执行顺序  from WHERE GROUP BY SELECT ORDER BY
	-- 查询每个工种的最高工资
			select max(salary) ,job_id from employees GROUP BY job_id;
	-- 查询每个位置的部门个数
			select count(*),location_id from departments GROUP BY location_id;
	-- 2.添加筛选条件
			select avg(salary),department_id from employees where email like'%a%' GROUP BY department_id;
	-- 3.查询复杂筛选条件
			-- 查询哪个部门的员工个数大于2
			select count(*),department_id from  employees GROUP BY department_id
			HAVING count(*) > 2; -- having 进行分组后的筛选
	-- 4.查询每个工种有奖金的员工的最高工资大于12000的工种编号和最高工资
				-- 查询每个工种有奖金的员工的最高工资
			-- 原始表可以筛选用where  分组后用 HAVING	
			select max(salary),job_id from employees WHERE commission_pct is not NULL	
												GROUP BY job_id having max(salary) > 12000;-- 按工种分类
-- 添加复杂筛选条件  having 子句在分组后筛选  where 分组前筛选
											-- 分组函数做条件一定放在having子句中
	-- 1. 查询那个部门的员工个数大于2
			select department_id ,count(employee_id) from employees GROUP BY department_id having count(employee_id)>2;
			select department_id ,employee_id from employees;
	-- 2. 查询每个部门有奖金的员工的最高工资大于12000的工种编号和最高工资
			select department_id ,max(salary) from employees WHERE commission_pct is not null group by department_id HAVING max(salary)>12000;
			select job_id ,max(salary) from employees WHERE commission_pct is not null group by job_id HAVING max(salary)>12000;
	-- 3.查询领导编号大于102的每个领导的手下最低工资>5000的领导编号是哪个,以及最低工资
			select min(salary) ,manager_id from employees where manager_id >102 GROUP BY manager_id having min(salary)>5000;
--  按表达式分组
	-- 1.按照员工的姓名长度分组,查询每一组员工的个数,筛选员工个数大于5的有哪些
			select count(*),CONCAT(first_name,last_name) from employees GROUP BY LENGTH(concat(last_name,first_name)) having count(*)>5;
				-- GROUP BY  和 having  支持使用select 中定义的别名
				-- where 子句中是不支持的
			select count(*) c,LENGTH(CONCAT(first_name,last_name)) len from employees GROUP BY len having c>5;
	-- 2. 查询每个部门每个工种的平均工资 (多个条件进行分组,两个条件相同的分组)
				select avg (salary),department_id,job_id from employees GROUP BY department_id,job_id;
-- 添加排序
	-- 1. 查询每个部门每个工种的平均工资并按工资的降序排列
				select avg(salary),department_id,job_id from employees GROUP BY department_id,job_id ORDER BY avg(salary) desc;
						-- order by  也支持别名  
select avg(salary) pj,department_id di,job_id from employees WHERE department_id is not null GROUP BY department_id,job_id ORDER BY pj desc;
# 总结: GROUP BY 子句 可以根据单个或者多个字段分组
				#还可以根据函数分组
				#可以添加排序
				# 筛选时候 在分组前的条件用where where 不支持别名的
				# 筛选在分组后使用的是having子句  having支持别名




连接查询

sql 92
-- 连接查询 多表连接 
-- 当查询字段来自多个表的时候
  -- 笛卡尔乘积 : 在没有条件的连接时
select * from beauty;
select * from boys;
select name , boyname from boys,beauty where beauty.boyfriend_id=boys.id;


-- 连接查询的分类
	-- 按年代分类 
			-- sql 92  仅支持内连接
			-- sql 99 (推荐) 除外连接的全外连接不支持其他都支持

	-- 按功能分类
			-- 1. 内连接
					-- 等值连接
					-- 非等值连接
					-- 自连接
			-- 2. 外连接
					-- 左外连接
					-- 右外连接
					-- 全外连接
			-- 3. 交叉连接


-- 一、sql 92标准
-- 等值连接  实现:全部匹配后筛选   where可以为表取别名,为select语句提高便利
	-- 1. 当from语句起了别名  那么select语句必须使用别名类限定
		 -- 查询女神名和对应的男神名  
	select name,boyname from boys ,beauty where beauty.boyfriend_id=boys.id;
		 -- 查询员工名和对应的部门ming
	select last_name,department_name from employees,departments WHERE employees.department_id=departments.department_id;
		-- 查询员工名、工种号、工种名   
	select last_name ,employees.job_id,job_title from employees,jobs where employees.job_id = jobs.job_id;
	-- 2. 添加筛选条件  连接筛选用的是and
	     -- 查询有奖金的员工名,部门名
	select last_name ,department_name,commission_pct from employees e ,departments d WHERE e.department_id=d.department_id and e.commission_pct is not null;
		   -- 
	select last_name ,e.job_id,job_title from employees as e,jobs where e.job_id = jobs.job_id;
	-- 3. 查询城市名中第二个字符为o的部门名和城市名
	select d.department_name,l.city from departments d ,locations l WHERE d.location_id=l.location_id and subStr(l.city ,2,1)='o';
	select substr(city,2,1) from locations;
	-- 4.加分组 
		-- 查询每个城市的部门个数
		select count(*), city from locations l ,departments d  where l.location_id = d.location_id GROUP BY city; 
		-- 查询出有奖金的每个部门的部门名和部门领导标号的和该部门的最低工资
		select min(salary) ,d.department_name,d.manager_id from employees e ,departments d WHERE e.department_id=d.department_id and commission_pct is not null GROUP BY e.department_id;
	-- 6.加排序
		-- 查询每个工种的工种名和员工的个数,并按员工个数降序
		select j.job_title ,count(*) from employees e,jobs j WHERE e.job_id=j.job_id GROUP BY e.job_id ORDER BY count(*) desc;
	-- 7.可以三表连接
		-- 查询员工名,部门名和所在城市
		select e.first_name ,d.department_name ,l.city from employees e, departments d,locations l WHERE e.department_id=d.department_id and d.location_id=l.location_id;
-- 总结  
	-- ① 多表等值连接的结果是多表的交集部分
	-- ② n表连接,至少需要n-1个连接条件
	-- ③ 多表的顺序没有要求
	-- ④ 一般需要为表起别名
	-- ⑤ 可以搭配其他的子句  排序 分组等



-- 二、非等值连接   把条件改为非等的条件
	
	-- 查询员工的工资和工资级别
	select * from job_grades;
	select salary,grade_level from employees e , job_grades g WHERE salary BETWEEN g.lowest_sal and g.highest_sal ORDER BY e.salary;

-- 三、自连接   连接自己
		-- 查询 员工名和领导编号   领导也在自己的员工表中
	select e1.first_name ,e2.employee_id from employees e1 ,employees e2 WHERE e1.employee_id=e2.employee_id;
		-- 取别名
	select e.first_name ename,m.first_name manager from employees e,employees m WHERE e.manager_id=m.employee_id and e.first_name like 'S%';
-- 练习
	-- 显示员工表的最大工资 平均工资
	select max(salary),avg(salary) from employees;
	-- 查询员工表的job_id 中包含a和c 并且 a在c的前面
	select job_id from employees WHERE job_id like  '%a%e%';
	-- 获取当前函数 去掉前后空格 
	select CURDATE();
	select NOW();
	select trim("  sd  fsf  "); -- trim('字符' from '要去的 ')
	select trim("_"from'_djsk_djf___');
sql99

-- sql 99 连接查询
	/*
		语法
		select 查询列表
		from 表1 别名 【连接类型】
		join 表2 别名 
		on  连接条件
			[WHERE 筛选条件]
			【group by】
			[having 筛选条件]
			【order by 排序列表】
*/
-- 内连接  √  : INNER JOIN
-- 外连接
		-- 左外连接 √  :left 【outer】 JOIN
		-- 右外连接 √	 :right 【outer】join
		-- 全外连接    :full 【outer】 JOIN
-- 交叉连接      : CROSS



-- 内连接
		-- 等值连接 
		-- 非等值连接 
		-- 自连接
-- 等值连接  比92语法可读性更高   inner 可以省略  
	-- 1. 查询员工名,部门名
		select last_name ,department_name from employees e 
			inner join departments d on e.department_id = d.department_id;
	-- 2. 查询名字中包含e的员工名和工种名
		select last_name , job_title from employees e 
			inner join jobs j on e.job_id=j.job_id WHERE e.last_name like '%e%' ;
	-- 3. 添加分组和筛选
			-- 查询部门个数大于3的城市名和部门个数
			-- 先查询每个城市的部门个数
			-- 子筛选满足条件的
		select count(department_id) ,city  from departments d INNER JOIN locations l  on d.location_id = l.location_id 
		GROUP BY city having count(*)>3; 
	-- 4. 添加排序
			--
	-- 5. 查询员工名,部门名,工种名,安照部门名降序
		select last_name ,department_name,job_title from employees e
					inner join departments d on d.department_id = e.department_id
					inner join jobs j on j.job_id = e.job_id
					ORDER BY department_name desc;

-- 非等值连接
		-- 查询工资级别
		select salary ,grade_level from employees e join job_grades g 
			ON e.salary BETWEEN g.lowest_sal and g.highest_sal;
-- 自连接
		-- 查询员工名字,上级名字
		select e.last_name ,m.last_name from employees e 
			INNER JOIN employees m  on e.manager_id = m.employee_id;	
		-- 筛选以上 中 员工名包含e的
			select e.last_name ,m.last_name from employees e 
			INNER JOIN employees m  on e.manager_id = m.employee_id
				WHERE e.last_name like '%z%';	

-- 外连接   查询一个表中有,一个表中没有的  也是笛卡尔积的运用  主表全显示  
						--  从表没有显示null  结果分为两部分 一部分是连接条件成立 显示匹配的行
						--  没有匹配的  主表显示, 从表显示null 
						--  在sql 中 左外连接 左边的是主表,右外连接右边的是主表  主表显示在前

	-- 左外连接
	
		-- 右外连接
		-- 引入:查询没有男朋友在男神表的女神名 
		select * from beauty ;
		select * from boys ;
		select name,boys.* from beauty  LEFT JOIN 
				boys on beauty.boyfriend_id = boys.id
				where boys.id is null and name ='柳岩';
		-- 使用右外连接
		select b.name , bo.* from boys bo RIGHT JOIN 
			beauty b on bo.id=b.boyfriend_id;
	-- 
	-- 查询哪个部门没有员工  先把有和没有的都查出来再筛选
		select d.* ,e.employee_id from departments d LEFT JOIN 
			employees e on e.department_id = d.department_id
			WHERE employee_id is null;

	-- 全外 mysql 不支持
	-- 交叉连接
	select b.* ,bo.* from beauty b cross  join boys bo;
联合查询


-- 语法 查询语句一 union 查询语句二;
-- 查询多个表  多个表中没有连接关系 但查询结果一致的情况
select * from employees where email like "%a%"
union
select * from employees where department_id >90;
select * from employees where email like "%a%" or department_id>90;


-- 应用场景:  查询中国用户中年龄大于12的信息 以及外国用户中年邻大于
-- 这个是两个表的信息
select  id,cname,csex from t_ca where csex='男'
union select t_id ,tname ,tgender from t_ua WHERE t_gender ='male';

-- 整个数据库表的数据  合并成一个结果  搜索  热点数据查询
-- 

-- 注意事项  :如果查询的列数不同的情况是不行的  多条查询的列数是一致的
					-- :查询信息的数据类型 和数据的顺序最好一致
					-- :两个表的数据重复会自动去重  不希望去重要加上  union all 


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值