力扣sql练习题-计算平均数-员工奖金问题

240 阅读1分钟

题目: 每台机器的进程平均运行时间

案例:

计算平均数.png

思路:通过round函数来保留小数,通过avg来统计平均数,通过if判断“start”状态

为什么avg的后面要乘以个2,这里可能会有一些疑惑,我的理解是avg里面的if做了四次判断,有四个数,它会除以4,但是start和end是一对的,只需要除以2 所以,在末尾需要乘以个2

解答:

select machine_id , round (avg(if(activity_type='start',-timestamp,timestamp))*2,3)
processing_time from Activity gourp by machine_id

题目:求员工的奖金小于1000 的员工姓名和奖金

员工奖金.png

我的解法:

  • 通过empId关联两张表,形成一张表,在判断这张表的bonus是否小于1000 或者是 null
select c.name,c.bonus from (select a.name,b.bonus from Employee a  left join Bonus
b on a.empId  = b.empId ) c where c.bonus<1000 or c.bonus is null

大佬解法:

左外连接,限制bouns小于一千或者为空值即可,使用ifnull 就可以对sql进行优化~

select t1.name , t2.bonus from employee t1 left join Employee t2 on 
t1.empid=t2.empid where ifnull(bonus,0)<1000

关于join on and 和 join on where 的理解

关于join on and

on条件是在生成临时表时使用的条件,on条件是对left join的右表进行条件过滤,它不管on条件是否为真,但依然返回左表的所有行,右表中没有的补为NULL 也就是说on中左表的限制条件只影响右表的匹配内容,不影响返回行数。 在本题中,题目要求没有奖金的仍然返回NULL,如果在join on后面使用了and bonus < 1000,结果会把所有员工都显示出来,包括bonus>1000的记录,但是bonus值显示NULL

关于join on where

where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有 left join 的含义(left join必须返回左边表的全部记录)了,条件不为真的就全部过滤掉。 在本题中,题目要求没有奖金的仍然返回NULL,使用left join on显示左表所有行,包括NULL,在生成临时表后,利用where过滤bonus>1000的记录