2012-04-17 67 views
2
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; 

以上Oracle查詢工作,併產生結果,例如:甲骨文RATIO_TO_REPORT和彙總

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% 

現在我想每個部門彙總得到的結果是這樣的:

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 

我有嘗試了各種各樣的東西,例如GROUPING SETS,但是我的PCT_JOB值是錯誤的。

+2

我認爲你需要,做了彙總外部查詢到這個包起來。 – FrustratedWithFormsDesigner 2012-04-17 17:47:50

+0

你是對的。我得到它的工作,但現在我想要下降的百分比,但在所有下降百分比後列出每個部門的彙總。但由於彙總是100%,因此首先列出。 – jeff 2012-04-17 18:15:08

+1

我認爲你可以做類似'... ORDER BY CASE當PCT = 100 THEN 1 ELSE 0 AS PCT END'不知道如果語法是100%,但我敢肯定它*可能有一個表達式在訂單條款中。 – FrustratedWithFormsDesigner 2012-04-17 18:18:11

回答

5

有一個功能GROUPING這是documented here。這個函數會告訴你給定的行是否是「超集合」行。然後您可以根據該行的值進行訂購。

請注意,我對PCT_JOB列的定義有點混亂,因爲我正在分組正常行和「超集合」行。

下面的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 

而且,我已經使用分組這裏設置,但有可能只使用:

GROUP BY home_dept, rollup(LINECODE) 

一個SQLFiddle is available這將讓你看到一個例子。

+0

謝謝,好吧,以便您的查詢工作。 Mine(above)在應用FrustratedWithFormsDesigner對外部查詢進行包裝的建議後工作。但是這兩個查詢都沒有按降序提供pct_job,而是最後彙總。請參閱上面我的問題的評論。我一直在玩的情況下,但我不能讓它匹配'100.00%' – jeff 2012-04-17 21:39:42

+0

好吧,我得到了ORDER BY CASE的工作。我不得不將TO_CHAR更改爲TRUNC,以便WHEN子句處理一個數字而不是一個字符。 – jeff 2012-04-17 21:46:27

+0

糟糕。忘了更新。這是正確的SQLFiddle頁面,但沒有在答案。現在修復。請不要在訂單中使用CASE,而是使用GROUPING而不是CASE可能會導致問題,因爲如果您對給定部門只有一行,因爲訂購可能是非確定性的 – 2012-04-17 22:00:16

3

這是一個不需要外部查詢的答案。它是基於麥克·邁爾斯的答案,但現在行代碼的分組的PARTITION BY子句中,也內ORDER BY子句指定:

SELECT 
    home_dept, 
    linecode, 
    SUM(total_hrs) AS total_hrs, 
    TO_CHAR(100 * RATIO_TO_REPORT (SUM(total_hrs)) 
      OVER (PARTITION BY home_dept, GROUPING(linecode)), 
      '990.00L', 'NLS_CURRENCY=%') AS pct_job 
FROM my_table 
GROUP BY GROUPING SETS ((home_dept), (home_dept, linecode)) 
ORDER BY home_dept, GROUPING(linecode), pct_job DESC 

上面的代碼使用GROUP BY GROUPING SETS但下面的GROUP BY也將工作:

GROUP BY home_dept, ROLLUP(linecode) 

而且FYI:原來的問題希望linecodes通過他們的百分比降序排列,而不是由線路碼值(即行代碼名稱)排序....但在給定的例子,結果「按百分比遞減」看起來與「按名稱遞增」相同。如果有人想看到名升序linecodes無論百分比,可以通過線順序更改爲這樣:

ORDER BY home_dept, linecode 
+0

謝謝。我會在不久的將來重新訪問這個應用程序,然後可以測試您的查詢。 – jeff 2014-08-05 20:47:41