mysql多表联合查询练习题

1、查询至少有一个员工的部门,显示部门编号,部门名称,部门位置,部门人数

/*
	1、查询至少有一个员工的部门,显示部门编号,部门名称,部门位置,部门人数
			列:d.deptno, d.dname, d.loc, 部门人数  (要查询部门人数需要使用分组)
			表:dept d, emp e
			条件:e.deptno = d.deptno
*/
SELECT *    	-- 查询部门表
FROM dept;

SELECT deptno, COUNT(*)		-- 根据分组查询员工表部门人数
FROM emp 
GROUP BY deptno;

-- 先将单独的两部分内容分别查询出来,在使用内链接把他们联合起来
-- 第一步:先分析有那些列,需要查询那些表,条件有什么
-- 第二步:将要查询的信息在子表中分别查询出来、
-- 第三步:将查询的信息链接在一起
-- 第四步:筛选出要使用的信息

SELECT d.*, z1.ent as '部门人数'   -- 在SELECT中不能直接只用 z1.COUNT(*) 要使用别名
FROM dept d, (SELECT deptno, COUNT(*) ent	FROM emp GROUP BY deptno) z1    -- 在from中添加子查询(内连接)
WHERE d.deptno = z1.deptno;					-- 去笛卡尔积   -- 使用了内连接40部门没有员工,所以没有显示在结果中


    2、列出所有员工的姓名及其直接上级的名字

/*
	2、列出所有员工的姓名及其直接上级的名字
		列:员工姓名、上级姓名
		表:emp e, emp m   -- 一个表重复查询两次 一个表示员工 一个表示 经理
		条件:e.empno = m.mgr
*/

SELECT e.ename, m.ename
FROM emp e, emp m
WHERE e.mgr = m.empno;    

-- 在表中曾阿牛没有对应的领导,如果想显示他就必须使用左外链接
-- SELECT e.ename, m.ename -- 可以使用ifnull将null值修改为指定信息
SELECT e.ename as '员工', IFNULL(m.ename,'BOSS') as '领导'
FROM emp e LEFT JOIN emp m
ON e.mgr = m.empno


3、列出受雇日期早于直接上级的所有员工的编号、姓名、部门名称

/*
	3、列出受雇日期早于直接上级的所有员工的编号、姓名、部门名称
		列:e.empno e.ename d.dname
		表:emp e, emp m, dept d
		条件:e.hiredate < m.hiredate

		思路:1、先进行单表查询(不查询部门名称),只查询部门编号
						列:e.empno, e.ename, e.deptno
						表:emp e, emp m;
						条件:去笛卡尔积(e.mgr = m.empno), e.hiredate < m.hiredate

		SELECT e.empno, e.ename, e.deptno -- , e.hiredate, m.ename, m.hiredate
		FROM emp e, emp m
		WHERE e.mgr = m.empno AND e.hiredate < m.hiredate;
*/ 

SELECT e.empno, e.ename, d.dname
FROM emp e, emp m, dept d
WHERE e.mgr = m.empno AND e.hiredate < m.hiredate AND e.deptno = d.deptno;

4、列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门

/*
	5、列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门
		列:*
		表:emp e, dept d
		条件:e.deptno = d.deptno

	先查出部门名称和员工信息
		SELECT * 
		FROM emp e, dept d
		WHERE e.deptno = d.deptno

	然后在查询没有员工的部门(右外连接)
*/

SELECT * 
FROM emp e RIGHT OUTER JOIN dept d
ON e.deptno = d.deptno

6、列出最低薪金大于15000的各种工作以及从事此工作的员工人数

/*
	6、列出最低薪金大于15000的各种工作以及从事此工作的员工人数
		列:job count(*)
		表:emp e
		条件:min(sal)>15000
		分组:job
		分组后查询用HAVING
*/
SELECT job, COUNT(*)
FROM emp e
GROUP BY job
HAVING MIN(sal) > 15000

7、列出在销售部工作的员工的姓名,假定不知道销售部的部门编号

/*
	7、列出在销售部工作的员工的姓名,假定不知道销售部的部门编号
		列:e.ename
		表:emp
		条件:e.deptno={SELECT deptno FROM dept WHERE dnam='销售部'}  -- 设置子查询
*/

SELECT * 
FROM emp e
WHERE e.deptno=(SELECT deptno FROM dept WHERE dname='销售部')

8、列出薪资高于公司工资平均薪金的所有员工信息,所在部门名称,上级领导,工资等级

/*
	8、列出薪资高于公司工资平均薪金的所有员工信息,所在部门名称,上级领导,工资等级
		-- 分别查询三张表中的信息
			SELECT * FROM emp;
			SELECT * FROM dept;
			SELECT * FROM salgrade;

	列:*
	表:emp e
	条件:sal>(查询出公司的平均工资)		-- 子查询

	8.1 列出薪资高于公司工资平均薪金的所有员工信息
		SELECT *
		FROM emp e
		WHERE e.sal>(SELECT AVG(sal) FROM emp) 

	8.2 加上:部门名称
		SELECT e.*, d.dname
		FROM emp e, dept d  -- 这样查询会少一条张三的信息。因为他没有部门,所以要才用左连接的方式
		WHERE e.sal>(SELECT AVG(sal) FROM emp) AND e.deptno = d.deptno

	8.4加上:上级领导
		SELECT e.*, d.dname, m.ename
		FROM emp e, dept d, emp m  -- 这样查询会少两条信息,张三没有部门,曾阿牛没有上级领导
		WHERE e.sal>(SELECT AVG(sal) FROM emp) AND e.deptno = d.deptno AND e.mgr = m.empno

	8.5加上:工资等级
		SELECT e.*, d.dname, m.ename, s.grade
		FROM emp e, dept d, emp m, salgrade s
		WHERE e.sal>(SELECT AVG(sal) FROM emp) AND e.deptno = d.deptno AND e.mgr = m.empno AND e.sal BETWEEN s.losal AND s.hisal  -- 工资只要在losal和hisal范围内就好查出等级

	8.6 使用左外链接查询缺省数据
	SELECT e.*, d.dname, m.ename, s.grade
	FROM 
		emp e LEFT OUTER JOIN dept d ON e.deptno = d.deptno
					LEFT OUTER JOIN emp m ON e.mgr = m.empno
					LEFT OUTER JOIN salgrade s ON e.sal BETWEEN s.losal AND s.hisal
	WHERE e.sal>(SELECT AVG(sal) FROM emp)
*/
SELECT e.*, d.dname, m.ename, s.grade
FROM 
	emp e LEFT OUTER JOIN dept d ON e.deptno = d.deptno
				LEFT OUTER JOIN emp m ON e.mgr = m.empno
				LEFT OUTER JOIN salgrade s ON e.sal BETWEEN s.losal AND s.hisal
WHERE e.sal>(SELECT AVG(sal) FROM emp)

    9、列出与庞统从事相同工作的所有员工及部门名称

/*
	9、列出与庞统从事相同工作的所有员工及部门名称
		列:e.*. d.dname
		表:emp e, dept d
		条件:job=(查询出庞统的工作)  -- 注意:去笛卡尔
*/

SELECT e.*, d.dname
FROM emp e, dept d
WHERE e.deptno = d.deptno AND job=(SELECT job FROM emp WHERE ename='庞统' )

 10、列出薪金高于在部门30工作的所有员工的薪资的员工姓名和薪金、部门名称

/*
	10、列出薪金高于在部门30工作的所有员工的薪资的员工姓名和薪金、部门名称。
		列:e.ename, e.sal, d.dname
		表:emp e, dept d
		条件:sal > all (30部门薪金)
*/

SELECT e.ename, e.sal, d.dname
FROM  emp e, dept d
WHERE e.deptno = d.deptno AND sal > ALL(SELECT sal FROM emp WHERE deptno=30)

11、 查出年份、利润、年增长比

/*
11、 查出年份、利润、年增长比

	11.1 -- 在同一行中的数据才能进行计算,所以一个要查询两次,然后在去笛卡尔积
		SELECT * 
		FROM tb_year y1, tb_year y2		-- 注意第一年的数据没有关联关系,所以无法查询,要使用左外链接查询
		WHERE y1.year = y2.year+1;

	11.2 左外链接查询
		SELECT * 
		FROM tb_year y1 LEFT OUTER JOIN tb_year y2
		ON y1.year = y2.year+1;
	11.3 计算年增长比
		-- 使用 ifnull 修改 null 数据显示类型,使用 concat 添加%号,使用 as 添加别名
			SELECT y1.*, IFNULL(CONCAT((y1.zz- y2.zz)/y2.zz*100,'%'), '0%')  AS '增长比'
			FROM tb_year y1 LEFT OUTER JOIN tb_year y2
			ON y1.year = y2.year+1;
*/
SELECT y1.*, IFNULL(CONCAT((y1.zz- y2.zz)/y2.zz*100,'%'), '0%')  AS '增长比'
FROM tb_year y1 LEFT OUTER JOIN tb_year y2
ON y1.year = y2.year+1;

数据源:mysql5.0.0

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');

-- ----------------------------
-- Table structure for tb_year
-- ----------------------------
DROP TABLE IF EXISTS `tb_year`;
CREATE TABLE `tb_year` (
  `year` int(11) default NULL,
  `zz` int(11) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tb_year
-- ----------------------------
INSERT INTO `tb_year` VALUES ('2010', '100');
INSERT INTO `tb_year` VALUES ('2011', '150');
INSERT INTO `tb_year` VALUES ('2012', '250');
INSERT INTO `tb_year` VALUES ('2013', '800');
INSERT INTO `tb_year` VALUES ('2014', '1000');

 

  • 10
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值