2009-08-04 13 views
0

J'ai écrit une requête pour collecter des données à afficher dans une boîte de mise à jour automatique & graphique de favoris dans Excel. Je voudrais utiliser le rollup pour créer des lignes récapitulatives pour chaque type de train_line (PF et MJ) à inclure dans le tableau Excel. Est-ce que je peux faire cela en utilisant Rollup?aide avec Oracle rollup

J'ai essayé de me faire une idée de Rollup, mais je ne vais pas loin. J'ai essayé juste de l'entourer de choses aléatoires dans mon groupe, mais ça n'a pas fait ce que je voulais.

Voici à quoi ressemblent les premières colonnes de résultats.

DUMP_YEAR DUMP_WEEK LINE MINE PRODUCT CODE 
2009    30  MJ  MJ C  MJ-C 
2009    30  PF  BR F  BR-F 
2009    30  PF  BR L  BR-L 
2009    30  PF  HD F  HD-F 
2009    30  PF  HD L  HD-L 
2009    30  PF  MA F  MA-F 
2009    30  PF  MA L  MA-L 
2009    30  PF  NM F  NM-F 
2009    30  PF  NM L  NM-L 
2009    30  PF  PA F  PA-F 
2009    30  PF  PA L  PA-L 
2009    30  PF  TP F  TP-F 
2009    30  PF  TP L  TP-L 
2009    30  PF  WA F  WA-F 
2009    30  PF  WA L  WA-L 
2009    30  PF  YA F  YA-F 

Et voici ma requête SQL.

select t.dump_year, 
     t.dump_week, 
     (case when t.product = 'L' or t.product = 'F' then 'PF' 
      when t.product = 'C' then 'MJ' 
      else null 
     end) as train_line,  
     t.mine_id, 
     t.product, 
     t.mine_id||'-'||t.product as code, 
     count(distinct t.tpps_train_id) as trains, 
     count(1) as wagons, 
     count(CASE WHEN w.tonnes >= 1121 THEN w.tonnes END) as overload, 
     round(count(CASE WHEN w.tonnes >= 1121 THEN w.tonnes END)/count(1)*100,1) as pct_ol, 
     min(t.dump_date) as first_train, 
     max(t.dump_date) as last_train,  
     119 as u_limit, 
     100 as target,  

     round(avg(w.tonnes),2) as average, 
     round(stddev(w.tonnes),2) as deviation, 
     round(min(w.tonnes),2) as minimum, 
     round(max(w.tonnes),2) as maximum, 
     round(percentile_disc(0.99) within group (order by (w.tonnes) desc),2) as pct_1st, 
     round((percentile_disc(0.75) within group (order by (w.tonnes) desc)),2)-round((percentile_disc(0.99) within group (order by (w.tonnes) desc)),2) as whisker1, 
     round(percentile_disc(0.75) within group (order by (w.tonnes) desc),2) as pct_25th, 
     round((percentile_disc(0.50) within group (order by (w.tonnes) desc)),2)-round((percentile_disc(0.75) within group (order by (w.tonnes) desc)),2) as box50, 
     round((percentile_disc(0.25) within group (order by (w.tonnes) desc)),2)-round(percentile_disc(0.50) within group (order by (w.tonnes) desc),2) as box75, 
     round((percentile_disc(0.01) within group (order by (w.tonnes) desc)),2)-round((percentile_disc(0.25) within group (order by (w.tonnes) desc)),2) as whisker99, 
     round(percentile_disc(0.50) within group (order by (w.tonnes) desc),2) as pct_50th, 
     round(percentile_disc(0.25) within group (order by (w.tonnes) desc),2) as pct_75th, 
     round(percentile_disc(0.01) within group (order by (w.tonnes) desc),2) as pct_99th 

    from 

    (
     select trn.mine_code as mine_id, 
       substr(trn.train_control_id,2,1) as port, 
       trn.train_tpps_id as tpps_train_id,  
       con.weight_total-con.empty_weight_total as tonnes  
     from widsys.train trn 
        INNER JOIN widsys.consist con 
         USING (train_record_id) 

     where trn.direction = 'N' 
       and (con.weight_total-con.empty_weight_total) > 10 
       and trn.num_cars > 10 
     ) w, 

     (
     select td.datetime_act_comp_dump as dump_date, 
       to_char(td.datetime_act_comp_dump-7/24, 'IYYY') as dump_year, 
       to_char(td.datetime_act_comp_dump-7/24, 'IW') as dump_week, 
       td.mine_code as mine_id, 
       td.train_id as tpps_train_id, 
       pt.product_type_code as product 
     from tpps.train_details td 
       inner join tpps.ore_products op 
       using (ore_product_key) 
       inner join tpps.product_types pt 
       using (product_type_key) 
     where to_char(td.datetime_act_comp_dump-7/24, 'IYYY') = 2009 
       and to_char(td.datetime_act_comp_dump-7/24, 'IW') = 30 
     order by td.datetime_act_comp_dump asc 
    ) t 
    where w.mine_id = t.mine_id 
     and w.tpps_train_id = t.tpps_train_id 

--having t.product is not null or t.mine_id is null 
    group by 
     t.dump_year, 
     t.dump_week, 
     (case when t.product = 'L' or t.product = 'F' then 'PF'when t.product = 'C' then 'MJ'else null end),  
     t.mine_id, 
     t.product 


order by train_line asc 

Répondre

9

Vous utiliseriez ROLLUP pour générer des sous-totaux hiérarchiques pour votre requête, à savoir:

SQL> WITH DATA AS (
    2  SELECT 'i' || MOD(ROWNUM, 1) dim1, 
    3   'j' || MOD(ROWNUM, 2) dim2, 
    4   'k' || MOD(ROWNUM, 3) dim3, 
    5   ROWNUM qty 
    6  FROM dual 
    7  CONNECT BY LEVEL <= 100 
    8 ) 
    9 SELECT dim1, dim2, dim3, SUM(qty) tot 
10 FROM DATA 
11 GROUP BY dim1, rollup(dim2,dim3) 
12 ORDER BY 1, 2, 3; 

DIM1 DIM2 DIM3   TOT 
----- ----- ----- ---------- 
i0 j0 k0   816 
i0 j0 k1   884 
i0 j0 k2   850 
i0 j0    2550 (*) 
i0 j1 k0   867 
i0 j1 k1   833 
i0 j1 k2   800 
i0 j1    2500 (*) 
i0      5050 (*) 

Rollup clause généré les lignes marquées (*)

Si vous voulez seulement obtenir un ensemble de sous-totaux et pas tous les niveaux hiérarchiques, vous pouvez utiliser le GROUPING SETS clause, à savoir:

SQL> WITH DATA AS (
    2  SELECT 'i' || MOD(ROWNUM, 1) dim1, 
    3   'j' || MOD(ROWNUM, 2) dim2, 
    4   'k' || MOD(ROWNUM, 3) dim3, 
    5   ROWNUM qty 
    6  FROM dual 
    7  CONNECT BY LEVEL <= 100 
    8 ) 
    9 SELECT dim1, dim2, dim3, SUM(qty) tot 
10 FROM DATA 
11 GROUP BY GROUPING SETS (
12  (dim1, dim2, dim3), -- detail 
13  (dim1) -- total 
14 ) 
15 ORDER BY 1, 2, 3; 

DIM1 DIM2 DIM3   TOT 
----- ----- ----- ---------- 
i0 j0 k0   816 
i0 j0 k1   884 
i0 j0 k2   850 
i0 j1 k0   867 
i0 j1 k1   833 
i0 j1 k2   800 
i0      5050 
+1

+1, et ce dernier groupe définit la notation peut être réécrite à « GROUP BY dim1 Rollup ((dim2, dim3)) Merci –

+0

Rob, je ne savais pas ce synthaxe: > –