MySQL多表查询

多表查询

1、分类

    -| 合并结果集(了解)

    -| 连接查询

    -| 子查询

合并结果集

  -| 要求被合并的表中,列的类型和列数相同

  -| union 去除重复行

  -| UNION ALL, 不去除重复行

 

select * from cd

union ALL

SELECT * FROM ab;

 

连接查询

1.分类

  -| 内连接

  -| 外连接

    -| 左外连接

    -| 右外连接

    -| 全外连接(MySQL不支持)

自然连接(属于一种简化)

 

2.内连接

  -| 方言:select * from 表1 别名1, 表2, 别名2 where 别名1.xx = 别名2.xx

  -| 标准:select * from 表1 别名1 inner join 表2 别名2 on 别名1.xx = 别名2.xx

  -| 自然: select * from 表1 别名1 natural join 表2 别名2

内连接查询出的所有记录都满足条件。

 

3. 外连接

    左外:select * from 表1 别名1 left outer join 表2 别名2 on 别名1.xx = 别名2.xx

      >左表记录无论是否满足条件都会查询出来,而右表只有满足条件才能出来。左表中不满足条件的记录,其右表部分为NULL

    左外自然:select * from 表1 别名1 NATURAL LEET OUTER JOIN 表2 别名2 ON 别名1.xx == 别名2.xx

    右外:select * from 表1 别名1 NATURAL RIGHT OUTER JOIN 表2 别名2 ON 别名1.xx = 别名2.xx

      >右表记录无论是否满足条件都会查询出来,而左表只有满足条件才能出来。右表中不满足条件的记录,其左表部分为NULL

      左外自然:select * from 表1 别名1 NATURAL RIGHT OUTER JOIN 表2 别名2 ON 别名1.xx == 别名2.xx

    全链接:可以使用UNION来完成全链接

子查询:

      查询中有查询(查看select关键字的个数!)

1.出现的位置

   where后作为条件存在

   from后作为表存在(多行多列) 

  2.条件

   单行单列:SELECT * FROM 表1 别名1 WHERE 列1 [=、 >、 <、 >=、 <=、 != ](SELECT 列 FROM 表2 别名2 WHERE 条件)

    多行单列:SELECT * FROM 表1 别名1 WHERE 列1 [IN、 ALL、 ANY ](SELECT 列 FROM 表2 别名2 WHERE 条件)

    单行多列:SELECT * FROM 表1 别名1 WHERE 列1 (列1, 列2)IN(SELECT 列 FROM 表2 别名2 WHERE 条件)

    多行多列:SELECT * FROM 表1 别名1 (SELECT ......)别名2 WHERE 条件

-- ---------------------mysql内连接查询(方言)----------------------
-- 查询的笛卡尔积
-- {a, b, c} {1, 2}
-- {a1, a2, b1, b2, c1, c2}
-- 在查询中会产生大量的垃圾数据
SELECT *
FROM emp, dept;   -- 会产生笛卡尔积

-- ----------加入查询条件-----------
SELECT * 
FROM emp, dept
WHERE emp.deptno = dept.deptno;

/*
	打印:所有员工的姓名、工资、以及部门名称(去笛卡尔积)
*/
SELECT e.ename as '姓名', e.sal as '工资', d.dname as '部门名称' 
FROM emp e, dept d  -- 为表加入别名
WHERE e.deptno = d.deptno;
-- ---------------------mysql内连接查询(标准)----------------------
-- 标准内连接查询(在开发中建议使用标准查询语句,保证兼容性,防止数据库变更时重写SQL语句)

SELECT e.ename as '姓名', e.sal as '工资', d.dname as '部门名称' 
FROM emp e INNER JOIN dept d   -- 查询的内连接
ON e.deptno = d.deptno;					-- 此处可以使用where关键字 但是作为标准使用方式要使用on

-- ---------------------mysql内连接查询(自然)----------------------
-- 自然查询  NATURAL(此方法可读性较低,不建议使用)
SELECT e.ename as '姓名', e.sal as '工资', d.dname as '部门名称' 
FROM emp e NATURAL JOIN dept d;   -- 使用natural关键字 在查询中系统会自动都去关联表中查找相同的列进行匹配

--  ---------------SQL查询外连接-------------------
/* 外连接有一住一次,左外(左表)为主
										即:emp e为主,主表中所有的记录无论是否满足,都打印出来
																			 当不满足条件时,右表部分使用null补位
 */
SELECT e.ename, e.sal, d.dname  -- 可以使用ifnull函数,将null变为给定信息
  -- SELECT e.ename, e.sal, IFNULL(d.dname,'无部门')
FROM emp e LEFT OUTER JOIN dept d     -- 左外连接
ON e.deptno = d.deptno;

-- 右链接
SELECT e.ename, e.sal, d.dname  -- 查询效果与左连接相反(表中财务部没有员工,只显示部门名称,其他列用null补位,张三没有与主表相连,所以无法查询到)
FROM emp e RIGHT OUTER JOIN dept d
ON e.deptno = d.deptno;

-- 全外链接(左表和右表没有出现的信息都要进行补位)
SELECT e.ename, e.sal, d.dname
FROM emp e FULL OUTER JOIN dept d
ON e.deptno = d.deptno;

-- 注意:mysql中不支持全外链接查询,可以使用结果合并集模拟次操作
SELECT e.ename, e.sal, d.dname
FROM emp e LEFT OUTER JOIN dept d
ON e.deptno = d.deptno   -- 注意此处不能出现分号(分号表示一条查询语句的结束)
UNION				-- 用结果集弥补全外查询
SELECT e.ename, e.sal, d.dname
FROM emp e RIGHT OUTER JOIN dept d
ON e.deptno = d.deptno;
-- ----------------------子查询------------------------------
/*
  查询本公司工资最高的员工的详细信息
  子查询可以出现的位置:
		FROM
		WHERE
*/

SELECT MAX(sal) FROM emp;   -- 查询最高工资

SELECT *			-- 查询指定工资(最高工资)的员工的所有信息
FROM emp e
WHERE sal=(SELECT MAX(sal) FROM emp);  -- 在查询条件中加入查询条件(子查询)

-- 出现位置在from中
SELECT e.empno, e.ename
FROM(SELECT * FROM emp WHERE deptno=30) e  -- 以部门为30的员工为基础进行二次查询,注意要取一个别名
WHERE e.empno = 1002;

-- 子查询的结果集分为:
	-- 单行单列, 多行单列、单行单列、 多行多列

/*单行单列:打印高于平均工资的所有员工*/
SELECT * 
FROM emp
WHERE sal > (SELECT AVG(sal) FROM emp);

/*多行单列:打印高于30部门所有员工工资的员工*/
SELECT * 
FROM emp
WHERE sal > ANY (SELECT sal FROM emp WHERE deptno=20);

/*多行单列:打印高于任意经理工资的员工*/
SELECT * 
FROM emp
WHERE sal > ANY (SELECT sal FROM emp WHERE job='经理');

/*单行多列:打印工作、部门和工资都与殷天正相同的员工  */
SELECT * 
FROM emp
WHERE(job, deptno, sal) IN (SELECT job, deptno, sal FROM emp WHERE ename='殷天正'); -- 可以理解为比较两个对象是否相等

/*多行多列:查询30部门中所以员工的编号和姓名*/
SELECT e.empno, e.ename
FROM(SELECT * FROM emp WHERE deptno=30) e

mysql数据源:

/*
Navicat MySQL Data Transfer

Source Server         : erp
Source Server Version : 50022
Source Host           : localhost:3306
Source Database       : exam

Target Server Type    : MYSQL
Target Server Version : 50022
File Encoding         : 65001

Date: 2019-09-12 16:43:52
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for dept
-- ----------------------------
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (
  `deptno` int(11) NOT NULL,
  `dname` varchar(50) default NULL,
  `loc` varchar(50) default NULL,
  PRIMARY KEY  (`deptno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of dept
-- ----------------------------
INSERT INTO `dept` VALUES ('10', '教研部', '北京');
INSERT INTO `dept` VALUES ('20', '学工部', '上海');
INSERT INTO `dept` VALUES ('30', '销售部', '广州');
INSERT INTO `dept` VALUES ('40', '财务部', '武汉');

-- ----------------------------
-- Table structure for emp
-- ----------------------------
DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp` (
  `empno` int(11) NOT NULL,
  `ename` varchar(50) default NULL,
  `job` varchar(50) default NULL,
  `mgr` int(11) default NULL,
  `hiredate` date default NULL,
  `sal` decimal(7,2) default NULL,
  `COMM` decimal(7,2) default NULL,
  `deptno` int(11) default NULL,
  PRIMARY KEY  (`empno`),
  KEY `fk_emp` (`mgr`),
  CONSTRAINT `fk_emp` FOREIGN KEY (`mgr`) REFERENCES `emp` (`empno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of emp
-- ----------------------------
INSERT INTO `emp` VALUES ('1001', '甘宁', '文员', '1013', '2000-12-17', '8000.00', null, '20');
INSERT INTO `emp` VALUES ('1002', '黛绮丝', '销售员', '1006', '2001-02-20', '16000.00', '3000.00', '30');
INSERT INTO `emp` VALUES ('1003', '殷天正', '销售员', '1006', '2001-02-22', '12500.00', '5000.00', '30');
INSERT INTO `emp` VALUES ('1004', '刘备', '经理', '1009', '2001-04-02', '29750.00', null, '20');
INSERT INTO `emp` VALUES ('1005', '谢逊', '销售员', '1006', '2001-09-28', '12500.00', '14000.00', '30');
INSERT INTO `emp` VALUES ('1006', '关羽', '经理', '1009', '2001-05-01', '28500.00', null, '30');
INSERT INTO `emp` VALUES ('1007', '张飞', '经理', '1009', '2001-09-01', '24500.00', null, '10');
INSERT INTO `emp` VALUES ('1008', '诸葛亮', '分析师', '1004', '2007-09-01', '30000.00', null, '20');
INSERT INTO `emp` VALUES ('1009', '曾阿牛', '董事长', null, '2001-11-17', '50000.00', null, '10');
INSERT INTO `emp` VALUES ('1010', '韦一笑', '销售员', '1006', '2001-09-08', '15000.00', '0.00', '30');
INSERT INTO `emp` VALUES ('1011', '周泰', '文员', '1008', '2007-05-28', '11000.00', null, '20');
INSERT INTO `emp` VALUES ('1012', '程普', '文员', '1006', '2001-12-03', '9500.00', null, '30');
INSERT INTO `emp` VALUES ('1013', '庞统', '分析师', '1004', '2001-12-09', '30000.00', null, '20');
INSERT INTO `emp` VALUES ('1014', '黄盖', '文员', '1007', '2002-01-23', '13000.00', null, '10');
INSERT INTO `emp` VALUES ('1015', '张三', '保洁员', '1009', '1999-09-09', '80000.00', '90000.00', '50');

-- ----------------------------
-- Table structure for salgrade
-- ----------------------------
DROP TABLE IF EXISTS `salgrade`;
CREATE TABLE `salgrade` (
  `grade` int(11) NOT NULL,
  `losal` int(11) default NULL,
  `hisal` int(11) default NULL,
  PRIMARY KEY  (`grade`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of salgrade
-- ----------------------------
INSERT INTO `salgrade` VALUES ('1', '7000', '12000');
INSERT INTO `salgrade` VALUES ('2', '12010', '14000');
INSERT INTO `salgrade` VALUES ('3', '14010', '20000');
INSERT INTO `salgrade` VALUES ('4', '20010', '30000');
INSERT INTO `salgrade` VALUES ('5', '30010', '99990');

-- ----------------------------
-- Table structure for stu
-- ----------------------------
DROP TABLE IF EXISTS `stu`;
CREATE TABLE `stu` (
  `sid` int(11) NOT NULL,
  `sname` varchar(50) default NULL,
  `age` int(11) default NULL,
  `gender` varchar(10) default NULL,
  `province` varchar(50) default NULL,
  `tuition` int(11) default NULL,
  PRIMARY KEY  (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of stu
-- ----------------------------
INSERT INTO `stu` VALUES ('1', '王永', '23', '男', '北京', '1500');
INSERT INTO `stu` VALUES ('2', '张雷', '25', '男', '辽宁', '2500');
INSERT INTO `stu` VALUES ('3', '李强', '22', '男', '山东', '3500');
INSERT INTO `stu` VALUES ('4', '宋永合', '18', '男', '成都', '4500');
INSERT INTO `stu` VALUES ('5', '宋永合', '20', '女', '湖北', '1000');

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值