一道数据库查询题

今天做这道题时有些困惑,记录一下.

首先是表的信息:
一道数据库查询题
问题:
查询每个领导及其(含领导自己)所属员工的平均工资,显示领导名称和平均工资

一开始自己的写法:

SELECT
	ld.NAME,(ld代表领导)
	AVG(yg.salary)
FROM
	employee ld,
	employee yg (yg 代表员工)
WHERE
	ld.`id`=yg.`mgr`
GROUP BY
	IFNULL(ld.`NAME`,yg.`NAME`);

结果:
一道数据库查询题

正确解答:

SELECT 
	ld.name, 
	AVG(yg.salary) 
FROM 
	employee yg 
LEFT JOIN 
	employee ld
ON 
	yg.`mgr`=ld.`id` 
GROUP BY  
	IFNULL(ld.name,yg.`NAME`);

结果:
一道数据库查询题
把自己的写法和正确答案进行比较,可以发现,我没有选择正确的连接方式
自己采用的是内连接: 查询的是两张表有交集的部分数据
正确写法用的是 左外连接: 查询左表的全部数据,和左右两张表有交集部分的数据
当两张表做笛卡尔积后,通过这两种方式筛选数据后,得到的数据是不一样的.

本题中,需要将领导以及下属分成一组做平均值,所以没有领导的 人也需要保留下来.

其次,还有一个小点就是分组条件, 在筛选后得到的的数据表,根据领导的姓名进行划分,没有领导的,把自己的名字作为分组标志. 即:
– 在某行数据中 当领导的名字 不是null时,以领导的名字作为分组标准,当领导是null时,就把这个老板作为员工看待分组.
– 两张表做笛卡尔积,并且筛选数据后,每一行拿出来一个标记作为分组依据, 领导名字 那一列 不是null 就把领导名字作为分组依据, 领导名字那一列为null 时, 就把 员工名字拿出来作为分组依据.

一道数据库查询题

IFNULL(ld.name,yg.`NAME`);

分组完之后 就可以求平均值了,(sql语句的执行顺序,还不是特别理解).

总的来说,
1.把一张表 当做两张表使用, 一张叫 ld ,一张叫 yg;
2. 两张表 做笛卡尔积 ,
3. 在条件 和 左外连接 的共同作用下 筛选数据,得到一张拼接后的新表,(包含了两表的所有列);
4. 根据新表中, 把原来是 领导表的 领导姓名那一列作为分组依据,(为空的拿 原来是员工表中的 员工姓名那一列作为分组依据),
5. 分组后,求平均值.
6. GG.

上一篇:C语言递归函数 计算s=1²+2²+3²+…+n²的值


下一篇:collect2:fatal error: ld terminated with signal 11 [Segmentation fault] 问题的解决