我有一个简单的查询:
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);
Run Code Online (Sandbox Code Playgroud)
我得到一个输出:
VAL1 VAL2 TOT
-------------------------------- -------------------------------- ----------
a a-details 1
a 1
b b-details 2
b 2
c c-details 3
c 3
Total Result 6
Run Code Online (Sandbox Code Playgroud)
但我需要一个输出,如:
VAL1 VAL2 TOT
-------------------------------- -------------------------------- ----------
a a-details 1
b b-details 2
c c-details 3
Total Result 6
Run Code Online (Sandbox Code Playgroud)
提前致谢.
Dav*_*dge 10
我发现使用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),());
Run Code Online (Sandbox Code Playgroud)
我怀疑它更有效率,因为它直接指定要计算的水平.
http://sqlfiddle.com/#!4/8301d/3
CUBE和ROLLUP用于自动生成大量聚合级别(例如,维度层次结构中的每个级别),如果您想从大型CUBE生成中消除一小部分级别,则可能存在使用GROUPING ID的情况设置,但GROUPING SET精确设计用于指定特定的聚合级别.
您可以使用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);
Run Code Online (Sandbox Code Playgroud)
输出:
NVL(VAL1,'TOTALRESULT') VAL2 TOT ----------------------- --------- ---------- a a-details 1 b b-details 2 c c-details 3 Total Result 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);
Run Code Online (Sandbox Code Playgroud)
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 Total Result 6 3
关于Rollup和相关主题的更多信息:Tim Hall关于Rollup和Cube
(编辑)
关于评论.你可以使用这个GROUPING功能:
GROUPING - 接受单个列作为参数,如果列包含由a
ROLLUP或CUBE操作作为小计的一部分生成的空值,则返回"1 ";对于任何其他值(包括存储的空值),包含"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);
Run Code Online (Sandbox Code Playgroud)
输出:
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 Total Result 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);
Run Code Online (Sandbox Code Playgroud)
输出:
NVL(VAL1,'TOTALRESULT') VAL2 TOT ----------------------- --------- ---------- a a-details 1 b b-details 2 c c-details 3 Total Result 6
在这里使用GROUPINGAskTom 的功能的想法.
| 归档时间: |
|
| 查看次数: |
19321 次 |
| 最近记录: |