日期:2014-05-17  浏览次数:20908 次

一道简单的分组合计疑问,求解
我用的oracle自带的scott/tiger 表

现在要查询 所有雇员的数量 和 分别在1980,1981,1982,1983(表中没有1983的雇员)加入公司的雇员数量,自设列标题。
我是这样写
SELECT TO_CHAR(hiredate,'YYYY') "YEAR",COUNT(empno)
FROM emp
GROUP BY ROLLUP(TO_CHAR(hiredate,'YYYY'))
ORDER BY TO_CHAR(hiredate,'YYYY');
结果为
YEAR COUNT(empno)
1980 1
1981 10
1982 1
1987 2
  14
问题来了,
如果我想出现的结果为
YEAR COUNT(empno)
1980 1
1981 10
1982 1
1983 0
1987 2
  14
因为hiredate中是没1983年份进来的员工,所以select出来的结果不可能有1983行的,可不可以让结果里加上1983行的数据,可以的话应该如何写,谢谢


------解决方案--------------------
楼主,你好
题目:查询分别在1980,1981,1982,1983加入公司的雇员数量
分析:没有1983,需要自定义出这个字段
方案一:建立一个年份表,该表包含所需的所有年份,和查询结果做左连接查询,此方案容易理解,但是需要建表,应该不是楼主本意,故略。
方案二:写纯查询语句罗列年份,和查询结果做左连接查询,这里用到了一个行转列的小技巧,实际上也是将其作为表来使用。
方案二语句如下:
SQL code

SELECT x.a years,nvl(y.counts,0) counts
FROM (SELECT a
      FROM (SELECT '1980' a, '1981' b, '1982' c, '1983' d FROM dual)
      UNION ALL
      SELECT b
      FROM (SELECT '1980' a, '1981' b, '1982' c, '1983' d FROM dual)
      UNION ALL
      SELECT c
      FROM (SELECT '1980' a, '1981' b, '1982' c, '1983' d FROM dual)
      UNION ALL
      SELECT d
      FROM (SELECT '1980' a, '1981' b, '1982' c, '1983' d FROM dual)) x,
     
     (SELECT TO_CHAR(e.hiredate, 'yyyy') years, COUNT(1) counts
      FROM emp e
      WHERE TO_CHAR(e.hiredate, 'yyyy') IN ('1980', '1981', '1982', '1983')
      GROUP BY TO_CHAR(e.hiredate, 'yyyy')) y
WHERE x.a = y.years(+)
ORDER BY 1

测试结果:
1    1980    1
2    1981    10
3    1982    1
4    1983    0

------解决方案--------------------
SQL code

建这么一张表吧,用来存放需要分组的年份:
create table year(
       year date
);
1980-1-1
1981-1-1
1982-1-1
1983-1-1
1987-1-1

统计sql如下:
select 
       to_char(t1.year,'yyyy') YEAR,count(t2.empno) EMP_NUM
from year t1 left join emp t2 on to_char(t1.year,'yyyy')=to_char(t2.hiredate,'yyyy')
group by to_char(t1.year,'yyyy')
order by to_char(t1.year,'yyyy')

------解决方案--------------------
表中数据:


实测结果: