функция оракула с несколькими столбцами

У меня простой запрос:

WITH data(val1, val2, val3) AS ( SELECT 'a' ,'a-details' ,'1' FROM DUAL UNION ALL SELECT 'b' ,'b-details' ,'2' FROM DUAL UNION ALL SELECT 'c' ,'c-details' ,'3' FROM DUAL ) SELECT NVL(val1,'Total Result'), val2, SUM(val3) tot from data group by rollup(val1, val2); 

Я получаю вывод вроде:

 VAL1 VAL2 TOT -------------------------------- -------------------------------- ---------- a a-details 1 a 1 b b-details 2 b 2 c c-details 3 c 3 Total Result 6 

Но мне нужен вывод:

 VAL1 VAL2 TOT -------------------------------- -------------------------------- ---------- a a-details 1 b b-details 2 c c-details 3 Total Result 6 

Заранее спасибо.

    Мне легче определить точные множества, которые мне нужны, с предложением GROUPING SET:

     WITH data(val1, val2, val3) AS ( SELECT 'a' ,'a-details' ,'1' FROM DUAL UNION ALL SELECT 'b' ,'b-details' ,'2' FROM DUAL UNION ALL SELECT 'c' ,'c-details' ,'3' FROM DUAL ) SELECT NVL(val1,'Total Result'), val2, SUM(val3) tot from data group by grouping sets ((val1, val2),()); 

    Я подозреваю, что он более эффективен, так как он напрямую определяет уровни для расчета.

    http://sqlfiddle.com/#!4/8301d/3

    CUBE и ROLLUP удобны для создания большого количества уровней агрегации автоматически (например, каждый уровень в размерной иерархии), и может быть случай использования GROUPING ID, если вы хотите исключить небольшое подмножество уровней из большого CUBE-сгенерированного set, но GROUPING SET точно предназначен для указания конкретных уровней агрегации.

    Выражение GROUPING_ID

    Вы можете использовать выражение GROUPING_ID для фильтрации тех уровней промежуточных итогов, которые вам нужны:

     WITH data AS ( SELECT 'a' AS val1 ,'a-details' AS val2 , '1' AS val3 FROM DUAL UNION ALL SELECT 'b' ,'b-details' ,'2' FROM DUAL UNION ALL SELECT 'c' ,'c-details' ,'3' FROM DUAL ) SELECT NVL(val1,'Total Result'), val2, SUM(val3) tot from data group by ROLLUP(val1, val2) HAVING GROUPING_ID(val1, val2) IN (0, 3); 

    Вывод:

      NVL (VAL1, TOTALRESULT) VAL2 TOT
     ----------------------- --------- ----------
     a-детали 1 
     b b-details 2 
     c c-details 3 
     Итоговый результат 6 

    GROUPING_ID возвращает 0 для строк без промежуточных итогов, 1 для первого уровня и т. Д., Мы можем взглянуть на возвращаемые им значения:

     WITH data AS ( SELECT 'a' AS val1 ,'a-details' AS val2 , '1' AS val3 FROM DUAL UNION ALL SELECT 'b' ,'b-details' ,'2' FROM DUAL UNION ALL SELECT 'c' ,'c-details' ,'3' FROM DUAL ) SELECT NVL(val1,'Total Result'), val2, SUM(val3) tot, GROUPING_ID(val1, val2) AS grp_id from data group by ROLLUP(val1, val2); 
      NVL (VAL1, TOTALRESULT) VAL2 TOT GRP_ID
     ----------------------- --------- ---------- -------- -
     a a-details 1 0 
     a 1 1 
     b b-details 2 0 
     b 2 1 
     c c-details 3 0 
     c 3 1 
     Итоговый результат 6 3 

    Проверить на SQLFiddle

    Подробнее о Rollup и смежных темах: Тим Холл о Rollup и Cube

    ( Изменить )

    Функция GROUPING

    Относительно комментария. Вы можете использовать функцию GROUPING :

    GROUPING – принимает единственный столбец в качестве параметра и возвращает «1», если столбец содержит нулевое значение, сгенерированное как часть промежуточного итога с помощью операции ROLLUP или CUBE или «0» для любого другого значения, включая сохраненные нулевые значения.

    Пример возвращаемых значений:

     WITH data AS ( SELECT 'a' AS val1 ,'a-details' AS val2 , '1' AS val3 FROM DUAL UNION ALL SELECT 'b' ,'b-details' ,'2' FROM DUAL UNION ALL SELECT 'c' ,'c-details' ,'3' FROM DUAL ) SELECT NVL(val1,'Total Result'), val2, SUM(val3) tot, grouping(val1), grouping(val2) from data group by ROLLUP(val1, val2); 

    Вывод:

      NVL (VAL1, TOTALRESULT) VAL2 TOT GROUPING (VAL1) GROUPING (VAL2)
     ----------------------- --------- ---------- -------- ------ --------------
     a a-details 1 0 0 
     a 1 0 1 
     b b-details 2 0 0 
     b 2 0 1 
     c c-details 3 0 0 
     c 3 0 1 
     Итоговый результат 6 1 1 

    Таким образом, ваш запрос должен выглядеть так:

     WITH data AS ( SELECT 'a' AS val1 ,'a-details' AS val2 , '1' AS val3 FROM DUAL UNION ALL SELECT 'b' ,'b-details' ,'2' FROM DUAL UNION ALL SELECT 'c' ,'c-details' ,'3' FROM DUAL ) SELECT NVL(val1,'Total Result'), val2, SUM(val3) tot from data group by ROLLUP(val1, val2) HAVING GROUPING(val1) = 1 OR (GROUPING(val1) + GROUPING(val2) = 0); 

    Вывод:

      NVL (VAL1, TOTALRESULT) VAL2 TOT
     ----------------------- --------- ----------
     a-детали 1 
     b b-details 2 
     c c-details 3 
     Итоговый результат 6 

    Идея использования функции GROUPING от AskTom, здесь .