Oracle SQL - Generate aggregate rows for certain r

2019-07-23 09:10发布

I have a table like below.

|FILE| ID |PARENTID|SHOWCHILD|CAT1|CAT2|CAT3|TOTAL|
|F1  | A1 |  P1    |     N   | 3  | 2  | 6  | 11  |
|F2  | A2 |  P2    |     N   | 4  | 7  | 3  | 14  |
|F3  | A3 |  P1    |     N   | 3  | 1  | 1  | 5   |
|F4  | LG1|        |     Y   | 6  | 3  | 7  | 16  |
|F5  | LG2|        |     Y   | 4  | 7  | 3  | 14  |

Now, Is it possible if I want to find the total (ie) aggregate of cat1, cat2, cat3 & total only for rows which has showChild as 'Y' and add that to the resultset.

|Tot| Res | Res | N | 10 | 10 | 10 | 30 |

Expected final output:

|FILE| ID |PARENTID|SHOWCHILD|CAT1|CAT2|CAT3|TOTAL|
|F1  | A1 |  P1    |     N   | 3  | 2  | 6  | 11  |
|F2  | A2 |  P2    |     N   | 4  | 7  | 3  | 14  |
|F3  | A3 |  P1    |     N   | 3  | 1  | 1  | 5   |
|F4  | LG1|        |     Y   | 6  | 3  | 7  | 16  |
|F5  | LG2|        |     Y   | 4  | 7  | 3  | 14  |
|Tot | Res|  Res   |     N   | 10 | 10 | 10 | 30  |

Here I have added the Tot row(last row) after considering only the rows which has showchild as 'Y' and added that to the resultset.

I am trying for a solution without using UNION

Any help on achieving the above results is highly appreciated.

Thank you.

3条回答
淡お忘
2楼-- · 2019-07-23 09:28

One approach would be to use a union:

WITH cte AS (
    SELECT "FILE", ID, PARENTID, SHOWCHILD, CAT1, CAT2, CAT3, TOTAL, 1 AS position
    FROM yourTable
    UNION ALL
    SELECT 'Tot', 'Res', 'Res', 'N', SUM(CAT1), SUM(CAT2), SUM(CAT3), SUM(TOTAL), 2
    FROM yourTable
    WHERE SHOWCHILD = 'Y'
)

SELECT "FILE", ID, PARENTID, SHOWCHILD, CAT1, CAT2, CAT3, TOTAL
FROM cte
ORDER BY
    position,
    "FILE";

enter image description here

Demo

查看更多
啃猪蹄的小仙女
3楼-- · 2019-07-23 09:28

You can try using UNION

select FILE,ID ,PARENTID,SHOWCHILD,CAT1,CAT2,CAT3,TOTAL from table1
union 
select 'Tot','Res','Res','N',sum(cat1), sum(cat2),sum(cat3), sum(total)
from table1 where SHOWCHILD='Y'
查看更多
等我变得足够好
4楼-- · 2019-07-23 09:43

I see you already accepted an answer, but you did ask for a solution that did not involve UNION. One such solution would be to use GROUPING SETS.

GROUPING SETS allow you to specify different grouping levels in your query and generate aggregates at each of those levels. You can use it to generate an output row for each record plus a single "total" row, as per your requirements. The function GROUPING can be used in expressions to identify whether each output row is in one group or the other.

Example, with test data:

with input_data ("FILE", "ID", PARENTID, SHOWCHILD, CAT1, CAT2, CAT3, TOTAL ) AS (
SELECT 'F1','A1','P1','N',3,2,6,11 FROM DUAL UNION ALL
SELECT 'F2','A2','P2','N',4,7,3,14 FROM DUAL UNION ALL
SELECT 'F3','A3','P1','N',3,1,1,5 FROM DUAL UNION ALL
SELECT 'F4','LG1','','Y',6,3,7,16 FROM DUAL UNION ALL
SELECT 'F5','LG2','','Y',4,7,3,14 FROM DUAL )
SELECT decode(grouping("FILE"),1,'Tot',"FILE") "FILE", 
       decode(grouping("ID"),1,'Res',"ID") "ID",
       decode(grouping(parentid),1, 'Res',parentid) parentid, 
       decode(grouping(showchild),1, 'N',showchild) showchild, 
       decode(grouping("FILE"),1,sum(decode(showchild,'Y',cat1,0)),sum(cat1)) cat1, 
       decode(grouping("FILE"),1,sum(decode(showchild,'Y',cat2,0)),sum(cat2)) cat2, 
       decode(grouping("FILE"),1,sum(decode(showchild,'Y',cat3,0)),sum(cat3)) cat3, 
       decode(grouping("FILE"),1,sum(decode(showchild,'Y',total,0)),sum(total)) total 
from input_data
group by grouping sets (("FILE", "ID", parentid, showchild), ())
+------+-----+-----+----------+-----------+------+------+------+-------+
| FILE | F2  | ID  | PARENTID | SHOWCHILD | CAT1 | CAT2 | CAT3 | TOTAL |
+------+-----+-----+----------+-----------+------+------+------+-------+
| F1   | F1  | A1  | P1       | N         |    3 |    2 |    6 |    11 |
| F2   | F2  | A2  | P2       | N         |    4 |    7 |    3 |    14 |
| F3   | F3  | A3  | P1       | N         |    3 |    1 |    1 |     5 |
| F4   | F4  | LG1 |  -       | Y         |    6 |    3 |    7 |    16 |
| F5   | F5  | LG2 |  -       | Y         |    4 |    7 |    3 |    14 |
| Tot  | Tot | Res | Res      | N         |   10 |   10 |   10 |    30 |
+------+-----+-----+----------+-----------+------+------+------+-------+
查看更多
登录 后发表回答