from子句的聚合函数

时间:2015-12-22 07:09:18

标签: sql oracle11g

一个查询,该查询应该提供具有年份作为列名和在该年度雇用的员工数量的输出。雇用日期将在hire_date列中。 我写了一个类似的代码 SELECT count(e.employee_id) total, count(a.employee_id) _2002, count(b.employee_id) _2003, count(c.employee_id) _2004, count(d.employee_id) _2005 FROM hr.employees e, (select employee_id from hr.employees where extract(year from hire_date)=2002) a, (select employee_id from hr.employees where extract(year from hire_date)=2003) b, (select employee_id from hr.employees where extract(year from hire_date)=2004) c, (select employee_id from hr.employees where extract(year from hire_date)=2005) d;
它在每一列中都显示为“0”。哪里出错了?

注意:所有条件都有数据。

2 个答案:

答案 0 :(得分:1)

我使用狭缝不同的方法得到了结果 SELECT count(employee_id) total, t1.a _2002, t2.b _2003, t3.c _2004, t4.d _2005 FROM hr.employees, (select count(employee_id) as a from hr.employees where extract(year from hire_date)=2002) t1, (select count(employee_id) as b from hr.employees where extract(year from hire_date)=2003) t2, (select count(employee_id) as c from hr.employees where extract(year from hire_date)=2004)t3, (select count(employee_id) as d from hr.employees where extract(year from hire_date)=2005) t4 group by t1.a , t2.b ,t3.c ,t4.d; 它给出了相同的答案。但我想知道为什么问题中的查询 不工作。请给我原因。 谢谢。

答案 1 :(得分:1)

  
      
  • 通过观察您的代码,您在 FROM子句中使用多个表,并使用逗号作为分隔符,这是一个 IMPLICIT CROSS JOIN ,它返回笛卡尔积连接中表的行数。其结果将是表A中的行乘以表B中的行与1:1匹配。如果每个表有10行并且具有1:1匹配,那么结果将是100行(简而言之,它返回匹配的所有行from both tables)。在您的情况下,您的表列表不会由于WHERE子句/条件使得它们的行唯一所以匹配行,因此结果显然等于0.

  •   
  • 或者,您只需使用 CASE STATEMENT 并汇总函数 SUM 即可获得预期结果,而无需使用多个表或加入。就像这样:

  •   
SELECT count(employee_id) total, 
            SUM(CASE WHEN EXTRACT(YEAR FROM hire_date)=2002 THEN 1 ELSE 0 END ) col_1999,
            SUM(CASE WHEN EXTRACT(YEAR FROM hire_date)=2003 THEN 1 ELSE 0 END ) col_1998, 
            SUM(CASE WHEN EXTRACT(YEAR FROM hire_date)=2004 THEN 1 ELSE 0 END ) col_1997, 
            SUM(CASE WHEN EXTRACT(YEAR FROM hire_date)=2005 THEN 1 ELSE 0 END ) col_1996 
            FROM hr.employees ;
  

请注意,在查询中使用逗号分隔多个表(IMPLICT JOIN)仍在使用ORACLE,但最好使用EXPLICIT JOIN。 Read this to know why it is better to use EXPLICIT than IMPLICIT JOIN