题目: 每台机器的进程平均运行时间
案例:
思路:通过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 的员工姓名和奖金
我的解法:
- 通过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的记录