Oracle RATIO_TO_REPORT和Rollup

jef*_*eff 2 sql oracle

SELECT HOME_DEPT, LINECODE, SUM(TOTAL_HRS),  
       TO_CHAR ( 
       100*RATIO_TO_REPORT(SUM(TOTAL_HRS))
       OVER (PARTITION BY HOME_DEPT), 
       '990.00L', 'NLS_CURRENCY=%'
       ) PCT_JOB
       FROM TABLE 
       GROUP BY HOME_DEPT, LINECODE ORDER BY HOME_DEPT ASC, PCT_JOB DESC;
Run Code Online (Sandbox Code Playgroud)

上面的Oracle查询工作并生成结果:

DEPT1 LINECODE1 100 50% 
DEPT1 LINECODE2  50 25%
DEPT1 LINECODE3  50 25%

DEPT2 LINECODE1  20 12.5% 
DEPT2 LINECODE2  20 12.5%
DEPT2 LINECODE3  20 12.5%
DEPT2 LINECODE4  20 12.5%
DEPT2 LINECODE5  20 12.5%
DEPT2 LINECODE6  20 12.5%
DEPT2 LINECODE7  20 12.5%
DEPT2 LINECODE8  20 12.5%
Run Code Online (Sandbox Code Playgroud)

现在我想按部门汇总以获得结果:

DEPT1 LINECODE1 100  50% 
DEPT1 LINECODE2  50  25%
DEPT1 LINECODE3  50  25%
DEPT1           200 100%  <--- desired

DEPT2 LINECODE1  20  12.5% 
DEPT2 LINECODE2  20  12.5%
DEPT2 LINECODE3  20  12.5%
DEPT2 LINECODE4  20  12.5%
DEPT2 LINECODE5  20  12.5%
DEPT2 LINECODE6  20  12.5%
DEPT2 LINECODE7  20  12.5%
DEPT2 LINECODE8  20  12.5%
DEPT2           160 100.0%    <--- desired
Run Code Online (Sandbox Code Playgroud)

我尝试了各种各样的东西,比如GROUPING SETS但是我的PCT_JOB值是错误的.

Mik*_*ers 5

还有一个功能,GROUPING这是记录在这里.此函数将告诉您给定行是否为"超级聚合"行.然后,您可以根据该行的值进行排序.

请注意,我对PCT_JOB列的定义有点像kludge,因为我分别对正常行和"超级聚合"行进行分组.

下面的SQL查询应该可以满足您的需求.

select
  home_dept,
  linecode,
  total_hrs,
  to_char(
    100 * ratio_to_report(total_hrs) over (partition by home_dept, linecode_group),
    '990.00L', 'NLS_CURRENCY=%') as pct_job 
from (
  SELECT 
    HOME_DEPT, 
    LINECODE, 
    SUM(TOTAL_HRS) as total_hrs, 
    grouping(linecode) as linecode_group
  FROM my_TABLE 
  GROUP BY grouping sets ((home_dept), (HOME_DEPT, LINECODE))
)
ORDER BY HOME_DEPT ASC, linecode_group, pct_job desc
Run Code Online (Sandbox Code Playgroud)

另外,我在这里使用了分组集,但是可以使用:

  GROUP BY home_dept, rollup(LINECODE)
Run Code Online (Sandbox Code Playgroud)

一个SQLFiddle可用,这将让你看到一个例子.