Oracle:将查询中的“汇总”替换为其他内容

时间:2011-02-22 19:02:07

标签: sql oracle rollup

我需要重写一个没有汇总功能的简单查询。你能帮帮我吗?

这是一个原始查询:

  SELECT e.department_id, 
         e.job_id, 
         SUM(e.salary)
    FROM EMPLOYEES e
GROUP BY ROLLUP(e.department_id, e.job_id);

我想可以使用UNION语句重写,是吗?

3 个答案:

答案 0 :(得分:2)

不需要UNION,您可以使用GROUPING SETS。这将产生相同的结果,甚至是相同的解释计划:

  SELECT e.department_id, 
         e.job_id, 
         SUM(e.salary)
    FROM EMPLOYEES e
GROUP BY GROUPING SETS( (e.department_id, e.job_id), (e.department_id), () )

答案 1 :(得分:1)

您可以使用CTE来处理它(注意我通过连接创建了EMPLOYEE表,只是为了获得样本数据)。可能有更好的方法,但这是一种方式!

WITH EMPLOYEES AS(
    SELECT   MOD(LEVEL,5)  DEPARTMENT_ID 
           , LEVEL JOB_ID 
           , 1000*LEVEL SALARY
      FROM DUAL      
     CONNECT BY LEVEL < 10
)
, SUMMEDDATA AS(
  SELECT e.department_id, 
         e.job_id, 
         SUM(e.salary) SUMMED_SALARY
    FROM EMPLOYEES e
GROUP BY e.department_id, e.job_id
)
, SUMMEDJOB_ID AS(
  SELECT e.department_id, 
         SUM(e.salary) SUMMED_SALARY
    FROM EMPLOYEES e
GROUP BY e.department_id
)
, SUMMEDTOTAL AS(
  SELECT  
         SUM(e.salary) SUMMED_SALARY
    FROM EMPLOYEES e
)
SELECT DEPARTMENT_ID ,
       JOB_ID ,
       SUMMED_SALARY
  FROM SUMMEDDATA
UNION ALL
SELECT DEPARTMENT_ID ,
       NULL ,
       SUMMED_SALARY
  FROM SUMMEDJOB_ID
UNION ALL
SELECT NULL ,
       NULL ,
       SUMMED_SALARY
  FROM SUMMEDTOTAL
ORDER BY 1 NULLS LAST, 2 NULLS LAST ;

DEPARTMENT_ID          JOB_ID                 SUMMED_SALARY          
---------------------- ---------------------- ---------------------- 
0                      5                      5000                   
0                                             5000                   
1                      1                      1000                   
1                      6                      6000                   
1                                             7000                   
2                      2                      2000                   
2                      7                      7000                   
2                                             9000                   
3                      3                      3000                   
3                      8                      8000                   
3                                             11000                  
4                      4                      4000                   
4                      9                      9000                   
4                                             13000   
                                              45000    

答案 2 :(得分:1)

以下内容应返回与汇总相同的结果,但性能较差且对“级别”的控制较少。

select e.department_id
      ,e.job_id
      ,SUM(e.salary)
  from EMPLOYEES e
 group 
    by e.department_id
      ,e.job_id
union all
select e.department_id
      ,null
      ,SUM(e.salary)
  from EMPLOYEES e
 group 
    by e.department_id
union all
select null
      ,null
      ,SUM(e.salary)
  from EMPLOYEES e;