2017-02-03 3 views
2

Я знаю, что этот вопрос довольно тривиален, но мне трудно писать SQL для примера, показанного ниже. Как показано в первой таблице, является результатом, что я генерируется и они нормально для аналитиков,Элементы группировки Oracle SQL

REGION SUBREGION SUM 
------ --------- ------ 
CORP CORP1  5 
CORP CORP2  10 
CORP CORP3  5 
SB  SB1   10 
SB  SB2   10 
MID  null  10 
LARGE null  20 

но для итогового отчета мне нужно, чтобы отобразить результат, как показано во второй таблице. Любые подсказки?

REGION SUM 
------ ---- 
CORP 20 
CORP1 5 
CORP2 10 
CORP3 5 
SB  20 
SB1  10 
SB2  10 
MID  10 
LARGE 20 
+0

Что вы пробовали? Как вы создали первый отчет (так как второй будет незначительным изменением). – AndySavage

ответ

0

звучит так, как будто вам нужно собрать одну и ту же таблицу разными полями, но получить оба назад, как если бы это было одно поле. Решение, которое приходит на ум, является UNION

select sum() as sum, REGION as sf from table group by REGION 
union ALL 
select sum() as sum, SUB_REGION as sf from table group by SUB_REGION; 

Надежда, что помогает

основанный на вопрос Дена, я добавляю, если вы не хотите, чтобы AGG в Vals, просто взять из суммы и группы и могли прямолинейной профсоюзу

select REGION as sf from table 
    union ALL 
    select SUB_REGION as sf from table; 

EDIT: еще одна мысль, может быть, когда вы делаете запрос в первую очередь, вы можете захотеть взглянуть на концепцию накопительные в качестве дополнительного пункта в вашей группе бушель и agg, может помочь решить это одним выстрелом.

+0

'sum()'? Вы уверены, что? –

+0

@ DanBracuk no Я не уверен, но его пример говорит «sum» как имя столбца, что подразумевает, что это будет подходящая функция agg для использования. – markg

1

Попробуйте использовать функции OLAP rollup и grouping как это:

select 
    nvl(subregion, region) region, sum("sum") 
from t 
group by region, rollup(subregion) 
having case when count(*) = 1 then 0 else 1 end = grouping(subregion); 

В приведенном выше,

having case when count(*) = 1 then 0 else 1 end = grouping(subregion); 

Вышеприведенные исключает rolluped строку, если имеется только одна строка для этой области, так что существует не являются дубликатами.

Также избегайте использования зарезервированных ключевых слов, таких как сумма или счет в ваших идентификаторах.

Демо:

SQL> with t(REGION ,SUBREGION ,s) as (
    2 select 'CORP' , 'CORP1' , 5 from dual union all 
    3 select 'CORP' , 'CORP2' , 10 from dual union all 
    4 select 'CORP' , 'CORP3' , 5 from dual union all 
    5 select 'SB'  ,'SB1'   ,10 from dual union all 
    6 select 'SB'  ,'SB2'   ,10 from dual union all 
    7 select 'MID'  , null , 10 from dual union all 
    8 select 'LARGE' , null , 20 from dual 
    9 ) 
10 select 
11 nvl(subregion, region) region, sum(s) 
12 from t 
13 group by region, rollup(subregion) 
14 having case when count(*) = 1 then 0 else 1 end = grouping(subregion); 

REGIO  SUM(S) 
----- ---------- 
SB1   10 
SB2   10 
SB   20 
MID   10 
CORP1   5 
CORP2   10 
CORP3   5 
CORP   20 
LARGE   20 

9 rows selected. 

SQL> 
0

Делают ту же самую группу по запросу вы делаете, но попробуйте использовать группу по ROLLUP:

Что-то вроде (непроверенные):

select region, subregion, sum(some_column) as sum 
from some_table 
group by rollup(region, subregion) 
order by region, subregion; 
1

Просто изменения ваша существующая ГРУППА BY к GROUPING SET:

SELECT 
    Coalesce(subregion, region) AS region, 
    Sum(column) 
FROM mytable 
GROUP BY GROUPING SETS(region, subregion) 
HAVING Coalesce(subregion, region) IS NOT NULL