sql基本训练

sql基本训练

一、基本款

CREATE TABLE `t_dept` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `deptName` VARCHAR(30) DEFAULT NULL,
 `address` VARCHAR(40) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
 
CREATE TABLE `t_emp` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `name` VARCHAR(20) DEFAULT NULL,
 `age` INT(3) DEFAULT NULL,
 `deptId` INT(11) DEFAULT NULL,
`empno` INT(11) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `idx_dept_id` (`deptId`)
 #CONSTRAINT `fk_dept_id` FOREIGN KEY (`deptId`) REFERENCES `t_dept` (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

INSERT INTO t_dept(id,deptName,address) VALUES(1,'华山','华山');
INSERT INTO t_dept(id,deptName,address) VALUES(2,'丐帮','洛阳');
INSERT INTO t_dept(id,deptName,address) VALUES(3,'峨眉','峨眉山');
INSERT INTO t_dept(id,deptName,address) VALUES(4,'武当','武当山');
INSERT INTO t_dept(id,deptName,address) VALUES(5,'明教','光明顶');
INSERT INTO t_dept(id,deptName,address) VALUES(6,'少林','少林寺');

INSERT INTO t_emp(id,NAME,age,deptId,empno) VALUES(1,'风清扬',90,1,100001);
INSERT INTO t_emp(id,NAME,age,deptId,empno) VALUES(2,'岳不群',50,1,100002);
INSERT INTO t_emp(id,NAME,age,deptId,empno) VALUES(3,'令狐冲',24,1,100003);

INSERT INTO t_emp(id,NAME,age,deptId,empno) VALUES(4,'洪七公',70,2,100004);
INSERT INTO t_emp(id,NAME,age,deptId,empno) VALUES(5,'乔峰',35,2,100005);

INSERT INTO t_emp(id,NAME,age,deptId,empno) VALUES(6,'灭绝师太',70,3,100006);
INSERT INTO t_emp(id,NAME,age,deptId,empno) VALUES(7,'周芷若',20,3,100007);

INSERT INTO t_emp(id,NAME,age,deptId,empno) VALUES(8,'张三丰',100,4,100008);
INSERT INTO t_emp(id,NAME,age,deptId,empno) VALUES(9,'张无忌',25,5,100009);
INSERT INTO t_emp(id,NAME,age,deptId,empno) VALUES(10,'韦小宝',18,NULL,100010);
第一条:查询所有有部门的员工及其部门信息
第二条:列出所有用户,并显示其机构信息
第三条:列出所有部门,并显示其部门的员工信息
第四条:查询没有加入任何部门的员工
第五条:查询没有任何员工的部门
第六条:查询所有员工和所有部门
第七条:查询没有加入任何部门的员工,以及查询出部门下没有任何员工的部门

  第一条:查询所有有部门的员工及其部门信息
	  select *
	  from t_emp e
	  inner join t_dept d
	  on e.deptId=d.id
  第二条:列出所有用户,并显示其机构信息
      select *
	  from t_emp e
	  left join t_dept d
	  on e.deptId=d.id
  第三条:列出所有部门,并显示其部门的员工信息
      select *
	  from t_emp e
	  right join t_dept d
	  on e.deptId=d.id
  第四条:查询没有加入任何部门的员工
      select *
	  from t_emp e
	  left join t_dept d
	  on e.deptId=d.id
	  where d.id is null
  第五条:查询没有任何员工的部门
      select *
	  from t_emp e
	  right join t_dept d
	  on e.deptId=d.id
	  where e.deptId is null
	  
  第六条:查询所有员工和所有部门
      select *
	  from t_emp e
	  left join t_dept d
	  on e.deptId=d.id
	  
	  union
	  
	  select *
	  from t_emp e
	  right join t_dept d
	  on e.deptId=d.id
	  
	  为何会重复?因为union是纵向连接。
	  union all:不可以去重,要求:纵向连接的表的列数要保持一致,对应的列的类型保持一致。
	  union:可以去重,要求:纵向连接的表的列数要保持一致,对应的列的类型保持一致。
	  
    第七条:查询没有加入任何部门的员工,以及查询出部门下没有任何员工的部门
	
      select *
	  from t_emp e
	  left join t_dept d
	  on e.deptId=d.id
	  where d.id is null
      union 
      select *
	  from t_emp e
	  right join t_dept d
	  on e.deptId=d.id
	  where e.deptId is null

二、拓展

1、求各个门派对应的掌门人名称
2、求所有当上掌门人的平均年龄
3、求所有人,对应的掌门是谁?
    拓展1:求各个门派对应的掌门人名称
	       select t_dept.*,t_emp.name from t_dept left join t_emp on t_dept.ceo=t_emp.id
    拓展2:求所有当上掌门人的平均年龄
	       select avg(t_emp.age) from t_dept inner join t_emp on t_dept.ceo=t_emp.id;
    
	拓展3:求所有人,对应的掌门是谁?
		第一种写法:
		  select e.id,e.name,ee.name
		  from t_emp e
		  left join t_dept d
		  on e.deptId=d.id
		  left join t_emp ee
		  on d.ceo = ee.id
		第二种写法:先求出每个门派的掌门人名称,再求每个人对应的 掌门人名称
	
			select *
			from t_emp ee
			left join (
			  select d.id,d.deptName,e.name
			 from t_dept d
			 left join t_emp e
			 on d.ceo = e.id
			) tmp 
			on ee.deptId=tmp.id
		
		第三种写法:子查询:select 子查询,每个人对对应的掌门id,再用掌门id求掌门人名称	
         explain select e.id,e.name,(select name from t_emp where id = d.ceo) ceoname
          from 	t_emp e
          left join t_dept d
          on e.deptId=d.id		

       第四种写法:子查询:from 子查询,每个人对对应的掌门id,再用掌门id求掌门人名称	
		select tmp.id,tmp.name,ee.name
		from (
			  select e.id,e.name,d.ceo
				  from 	t_emp e
				  left join t_dept d
				  on e.deptId=d.id	
		)	tmp 
		left join t_emp ee 
		on tmp.ceo = ee.id  
	      	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值