解决此练习的两种方法中哪一种更有效?

时间:2018-03-27 11:06:20

标签: sql performance

所以,这是练习:

创建一个查询,显示总统人数(job_id AD_PRES),总统总工资总额,行政副总裁人数(job_id AD_VP)以及这些副总裁的工资总额。< / em>的

向我展示的方式:

Select count(decode(job_id,'AD_PRES',1,0)) AS NumOfPres,
Sum(decode(job_id,'AD_PRES',salary,0) AS SumSalaryP,
count(decode(job_id,'AD_VP',1,0)) AS NumOfPres,
Sum(decode(job_id,'AD_VP',salary,0) AS SumSalaryVP
FROM EMPLOYEES;

这就是我所做的:

Select count (e.job_id),sum(e.salary),count(m.job_id),sum(m.salary)
FROM employees e join employees m on(e.job_id=m.job_id)
Where e.job_id='AD_PRES'
AND m.job_id='AD_VP';

所以,我想说加入更具可读性但是还有其他性能差异吗?

2 个答案:

答案 0 :(得分:0)

您的加入正在迫使员工之间的关系。如果没有这样的关系,那么所有结果都将返回0。

此外,您将所有担任总裁的员工与所有副总裁员工联系起来。因此,如果您有3位总统和10位副总裁,则联接将产生30行,并且将重复总和以计算总数,这在第一次查询中永远不会发生。

答案 1 :(得分:0)

练习没有指定返回单行,所以简单的方法是:

Select 
   job_id, 
   count(*),
   sum(salary)
FROM EMPLOYEES
where job_id in ('AD_PRES', 'AD_VP')
group by job_id

第一选择使用旧语法,并且不会返回正确的结果,因为count(decode(job_id,'AD_PRES',1,0))count(*)相同。

它正在读取所有行,应该有一个WHERE:

Select 
   sum(case when job_id = 'AD_PRES' then 1 else 0 end) AS NumOfPres,
   Sum(case when job_id = 'AD_PRES' then salary else 0 end) AS SumSalaryP,
   sum(case when job_id = 'AD_VP' then 1 else 0 end) AS  AS NumOfVPs,
   Sum(case when job_id = 'AD_PRES' then salary else 0 end) AS SumSalaryVP
FROM EMPLOYEES
where job_id in ('AD_PRES', 'AD_VP');

你的第二选择根本不起作用。您加入了匹配的job_ids,但其中一个是AD_PRES&#39;而另一个&#39; AD_VP&#39;,所以不匹配。

如果你想加入,那将是一个CROSS JOIN:

Select *
from 
 ( Select 
      count(*) AS NumOfPres,
      sum(salary) AS SumSalaryP
   FROM EMPLOYEES
   where job_id ='AD_PRES'
 )
cross join
 ( Select 
      count(*) AS NumOfVPs,
      sum(salary) AS SumSalaryVP
   FROM EMPLOYEES
   where job_id ='AD_VP'
 )