枢轴总数 - oracle

时间:2016-08-03 12:56:10

标签: oracle dynamic pivot totals

我正在尝试计算一个计数数据透视查询的总数。

id  |  kolomtellingwaarde  |  regeltellingwaarde |
-------------------------------------------------|
 1  |         Dutch        |         M           |
 2  |         Dutch        |         M           |
 3  |         English      |         F           |
 4  |         French       |         F           |
 5  |         French       |         M           |

以上是表格中数据的可视化。

FUNCTION pivot_func(p_seqanalytics IN NUMBER)
  RETURN    sys_refcursor
AS
  v_sql     varchar2 (32767);
  v_refcur  sys_refcursor;
BEGIN
  v_sql :=
    'SELECT *
     FROM   (SELECT kolomtellingwaarde,
                    regeltellingwaarde
        FROM analytics_bindingresults
        WHERE seqanalytics = ' || p_seqanalytics || ' )
    PIVOT  (COUNT (*)
       FOR kolomtellingwaarde IN (';
 FOR r IN
   (SELECT DISTINCT kolomtellingwaarde
    FROM   analytics_bindingresults
    WHERE seqanalytics = p_seqanalytics)
 LOOP
   v_sql := v_sql || '''' || r.kolomtellingwaarde || ''',';
 END LOOP;
 v_sql := rtrim (v_sql, ',') || ')) order  by 1';
 OPEN v_refcur FOR v_sql;
 RETURN v_refcur;
END pivot_func;

这是我用来转动表格的代码。它会给我这个结果:

Regeltellingwaarde  |  French  |   Dutch  |   English |
------------------------------------------------------|
        M           |    1     |     2    |      0    |
        F           |    1     |     0    |      1    |

因此,此查询的目的是让用户获得有多少男性/女性说语言的视觉效果。

我试图获得每列的总数和每行的总数。

结果应该是这样的:

       Dutch  English  French   Total
M        2       0       1        3
F        0       1       1        2
Total    2       1       2        5

有人可以帮我解决这个问题吗?

提前谢谢你, 布伦特

2 个答案:

答案 0 :(得分:1)

我尝试修改您的代码以满足您的需求。

<强> SETUP:

create table analytics_bindingresults(id, kolomtellingwaarde, regeltellingwaarde, seqanalytics) as ( 
select 1, 'Dutch'   ,'M', 1 from dual union all
select 2, 'Dutch'   ,'M', 1 from dual union all
select 3, 'English' ,'F', 1 from dual union all
select 4, 'French'  ,'F', 1 from dual union all
select 5, 'French'  ,'M', 1 from dual 
)

功能:

FUNCTION pivot_func(p_seqanalytics IN NUMBER)
  RETURN    sys_refcursor
AS
  v_sql     varchar2 (32767);
  vGroupSql varchar2 (32767);
  vSumSql   varchar2 (32767);
  v_refcur  sys_refcursor;
BEGIN
  v_sql :=
    'SELECT *
     FROM   (SELECT kolomtellingwaarde,
                    regeltellingwaarde
        FROM analytics_bindingresults
        WHERE seqanalytics = ' || p_seqanalytics || ' )
    PIVOT  (COUNT (*)
       FOR kolomtellingwaarde IN (';
 FOR r IN
   (SELECT DISTINCT kolomtellingwaarde
    FROM   analytics_bindingresults
    WHERE seqanalytics = p_seqanalytics)
 LOOP
   v_sql := v_sql || '''' || r.kolomtellingwaarde || ''',';
   vGroupSql := vGroupSql || 'sum("''' || r.kolomtellingwaarde || '''"),';
   vSumSql := vSumSql || '"''' || r.kolomtellingwaarde || '''"+';
 END LOOP;
 vGroupSql := 'regeltellingwaarde, ' || rtrim(vGroupSql, ',');
 vSumSql := 'sum(' || rtrim(vSumSql, '+') || ')';
 v_sql := rtrim (v_sql, ',') || ')) order  by 1';
 v_sql := 'select ' || vGroupSql || ', ' || vSumSql || ' as total from ( ' || v_sql || ' ) group by grouping sets (regeltellingwaarde, ())';
 dbms_output.put_line(v_sql);
 OPEN v_refcur FOR v_sql;
 RETURN v_refcur;
END pivot_func;

此调用pivot_func(1)提供此查询:

SELECT regeltellingwaarde,
         SUM("'Dutch'"),
         SUM("'French'"),
         SUM("'English'"),
         SUM("'Dutch'" + "'French'" + "'English'") AS total
    FROM (  SELECT *
              FROM (SELECT kolomtellingwaarde, regeltellingwaarde
                      FROM analytics_bindingresults
                     WHERE seqanalytics = 1) PIVOT (COUNT(*) FOR kolomtellingwaarde IN ('Dutch', 'French', 'English'))
          ORDER BY 1)
GROUP BY GROUPING SETS(regeltellingwaarde, (  ))

这是查询的结果:

R SUM("'DUTCH'") SUM("'FRENCH'") SUM("'ENGLISH'")      TOTAL
- -------------- --------------- ---------------- ----------
F              0               1                1          2
M              2               1                0          3
               2               2                1          5

基本上,我添加了一些普通的动态sql来计算每一行的总数,然后使用外部查询来分组和计算总计; GROUPING SETS使用的积分转到this

答案 1 :(得分:0)

您可以使用单个SQL查询

with add_totals as (
select
   t.regeltellingwaarde
  ,nvl(t.kolomtellingwaarde,'Total') kolomtellingwaarde
  ,count(t.id) id_count
from
  analitics_bindingresults t
group by
   t.regeltellingwaarde
  ,rollup(t.kolomtellingwaarde)
)
,piv_total as (
select * from add_totals
  pivot(
    sum(id_count) for kolomtellingwaarde in (
       'Dutch' dutch
      ,'English' english
      ,'French' french
      ,'Total' total
    )
  )
)
select
   nvl(pt.regeltellingwaarde,'Total') as "Regeltellingwaarde"
  ,nvl(sum(pt.dutch),0)               as "Dutch"
  ,nvl(sum(pt.english),0)             as "English"
  ,nvl(sum(pt.french),0)              as "French"
  ,nvl(sum(pt.total),0)               as "Total"
from
  piv_total pt
group by
  rollup(pt.regeltellingwaarde)
order by
  pt.regeltellingwaarde desc nulls last
;