2009-08-04 7 views
0

Ich habe eine Abfrage geschrieben, um einige Daten zu sammeln, um in einer automatisch aktualisierten Box anzuzeigen & Whisker-Grafik in Excel. Ich möchte Rollup verwenden, um Zusammenfassungszeilen für jeden Typ von train_line (PF und MJ) zu erstellen, die in das Excel-Diagramm aufgenommen werden sollen.Hilfe mit Oracle sql Rollup

Kann ich das mit Rollup tun?

Ich habe versucht, Rollup meinen Kopf zu bekommen, aber ich komme nicht weit. Ich habe versucht, es einfach in meiner Gruppe herumzupacken - aber es hat nicht getan, was ich wollte.

Hier sehen Sie, wie die ersten Spalten der Ergebnisse aussehen.

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 

Und hier ist meine SQL-Abfrage.

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 

Antwort

9

Sie ROLLUP verwenden würden hierarchische Zwischensummen für Ihre Anfrage zu erzeugen, das heißt:

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 (*) 

Die ROLLUP Klausel generiert die Zeilen markiert (*)

Wenn Sie nur eine Reihe von Zwischensummen und nicht alle hierarchischen Ebenen erhalten möchten, können Sie dieverwendenKlausel, dh:

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 und letztere Gruppierung setzt kann Notation „GROUP BY dim1 neu geschrieben werden, ROLLUP ((dim2, dim3)) –

+0

Dank Rob, ich nicht über diesen Synthax wusste: > –