今天做这道题时有些困惑,记录一下.
首先是表的信息:
问题:
查询每个领导及其(含领导自己)所属员工的平均工资,显示领导名称和平均工资
一开始自己的写法:
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.