2012-10-23 6 views
5

Listener di lunga data, chiamante per la prima volta. Sto usando Crystal Reports 2010.I report Crystal devono raggrupparsi in base all'intervallo di date derivato

Ho informazioni commerciali giornaliere che ho bisogno di raggruppare insieme se il volume non cambia. Ecco come sono i dati.

commerciale # BegDate DataFine Volume

1  1/1/2012 1/2/2012 500 
1  1/2/2012 1/3/2012 500 
1  1/3/2012 1/4/2012 1000 
1  1/4/2012 1/5/2012 750 
1  1/5/2012 1/6/2012 750 
1  1/6/2012 1/7/2012 500 
1  1/7/2012 1/8/2012 500 
1  1/8/2012 1/9/2012 500 

ho bisogno di simile a questa.

commerciale # DateRange Volume

1  1/1/2012 - 1/3/2012 500 
1  1/3/2012 - 1/4/2012 1000 
1  1/4/2012 - 1/6/2012 750 
1  1/6/2012 - 1/9/2012 500 

ho bisogno di gruppo dagli intervalli di date derivati ​​ma non sono sicuro di come ottenere questo risultato con Crystal. Qualche idea??

+0

penso che questa domanda è simile a http://stackoverflow.com/questions/13269569/drive-enddate-of -current-row-from-stardate-of-next-row/13418153 # 13418153 – WKordos

risposta

0
with w as (
    select 1 id, to_date('1/1/2012', 'mm/dd/yyyy') db, to_date('1/2/2012', 'mm/dd/yyyy') de, 500 s from dual 
    union all 
    select 1, to_date('1/2/2012', 'mm/dd/yyyy'), to_date('1/3/2012', 'mm/dd/yyyy'), 500 from dual 
    union all 
    select 1, to_date('1/3/2012', 'mm/dd/yyyy'), to_date('1/4/2012', 'mm/dd/yyyy'), 1000 from dual 
    union all 
    select 1, to_date('1/4/2012', 'mm/dd/yyyy'), to_date('1/5/2012', 'mm/dd/yyyy'), 750 from dual 
    union all 
    select 1, to_date('1/5/2012', 'mm/dd/yyyy'), to_date('1/6/2012', 'mm/dd/yyyy'), 750 from dual 
    union all 
    select 1, to_date('1/6/2012', 'mm/dd/yyyy'), to_date('1/7/2012', 'mm/dd/yyyy'), 500 from dual 
    union all 
    select 1, to_date('1/7/2012', 'mm/dd/yyyy'), to_date('1/8/2012', 'mm/dd/yyyy'), 500 from dual 
    union all 
    select 1, to_date('1/8/2012', 'mm/dd/yyyy'), to_date('1/9/2012', 'mm/dd/yyyy'), 510 from dual  
    ) 

select tmin.db, tmax.de, tmin.s 
from 
(  
    select 
     row_number() over (order by db) id, 
      db, 
      s 
    from 
    ( 
     select 
      db, 
      s, 
      case 
        when ps is null 
         then 1 
        when ps != s 
         then row_number() over (order by db) 
       else 0 end num 
     from (

      select 
        (db) 
        , (de) 
        , lag (s,1) over (ORDER BY db) ps     
        , s 


      from w 
      ) t 
) t1 
    where num != 0 
) tmin, 

(select 
    row_number() over (order by db) id, 
     de, 
     s 
from 
(  
    select 
      db, 
      de, 

      s, 
      case 
       when ps is null 
        then 1 
       when ps != s 
        then row_number() over (order by de desc) 
      else 0 end num 
    from (

     select 
        db 
       ,(de) 
       , lag (s,1) over (ORDER BY de desc) ps     
       , s     

     from w 
     order by db 
     ) t 
) t1 
where num != 0) tmax 

where tmin.id = tmax.id 
+0

-1 Risultati errati, nomi di variabili scadenti. –

+0

funziona ma non è comprensibile e quindi non è replicabile. +1 solo per il tuo interesse. – Rachcha

4
with w as (
select 1 id, to_date('1/1/2012', 'mm/dd/yyyy') start_date, to_date('1/2/2012', 'mm/dd/yyyy') end_date, 500 sales_volume from dual 
union all 
select 1, to_date('1/2/2012', 'mm/dd/yyyy'), to_date('1/3/2012', 'mm/dd/yyyy'), 500 from dual 
union all 
select 1, to_date('1/3/2012', 'mm/dd/yyyy'), to_date('1/4/2012', 'mm/dd/yyyy'), 1000 from dual 
union all 
select 1, to_date('1/4/2012', 'mm/dd/yyyy'), to_date('1/5/2012', 'mm/dd/yyyy'), 750 from dual 
union all 
select 1, to_date('1/5/2012', 'mm/dd/yyyy'), to_date('1/6/2012', 'mm/dd/yyyy'), 750 from dual 
union all 
select 1, to_date('1/6/2012', 'mm/dd/yyyy'), to_date('1/7/2012', 'mm/dd/yyyy'), 500 from dual 
union all 
select 1, to_date('1/7/2012', 'mm/dd/yyyy'), to_date('1/8/2012', 'mm/dd/yyyy'), 500 from dual 
union all 
select 1, to_date('1/8/2012', 'mm/dd/yyyy'), to_date('1/9/2012', 'mm/dd/yyyy'), 500 from dual  
) 

,t as (select sales_volume 
      ,start_date 
      ,end_date 
      ,lag (sales_volume,1) over (order by start_date) prev_sales_volume 
     from w 
     order by start_date) 
,u as (select * 
     from t 
     where nvl(prev_sales_volume,-1) != sales_volume 
     order by start_date) 
select start_date 
     ,nvl(lead (start_date,1) over (order by start_date),(select max(end_date) from w)) end_date 
     ,sales_volume 
from u 
order by start_date 
+0

Funziona perfettamente, sembra il minimo che si possa codificare per portare a termine il lavoro. Sto ancora cercando altre soluzioni. +1. – Rachcha

+0

La risposta migliore e più compatta che ho. Grazie! +50. – Rachcha

1

userei la funzione di soppressione "X-2" per nascondere tutti, ma l'ultimo da ogni riga, e precedente() e Next() per trovare i punti finali.

Gruppo per BegDate; sopprimere i dettagli e le sezioni del piè di pagina del gruppo.

Creare una funzione {} @UpdateCurrentBegDate qualche parte nell'intestazione del gruppo

WhilePrintingRecords;  
Global DateVar CurrentBegDate; 

If PreviousIsNull({table.Volume}) or Previous({table.Volume}) <> {table.Volume} 
    Then (//We found a new range 
     CurrentBegDate = {table.BegDate}; 
    ); 

""; //Display nothing on screen 

E una funzione {} @DisplayBegDate in cui è attualmente in fase di BegDate mostrato

EvaluateAfter({@UpdateCurrentBegDate}); 
Global DateVar CurrentBegDate; 

Vai alla sezione di esperti e fare clic su "X-2" accanto all'opzione Elimina (per la sezione dell'intestazione del gruppo). Questa è la formula per non

Not(NextIsNull({table.Volume}) or Next({table.Volume}) <> {table.Volume}) 

Se avete bisogno di fare totali o altri calcoli, si dovrebbe farlo nella funzione {} @UpdateCurrentBegDate (e che ci si vuole cambiare il nome in {} o @UpdateCurrentValues qualcosa di simile). Puoi anche creare una nuova funzione che controlli le informazioni Next() se vuoi solo cambiare le cose quando il gruppo cambia - usando le funzioni di totalizzazione predefinite includerai i valori nascosti.

+0

Grande, non ho visto il "Ho bisogno di una soluzione SQL pura" fino a dopo la pubblicazione di questo. Non lo cancellerò comunque, risponderà alla domanda originale. – EvilBob22

+0

Grazie per la risposta. Anche io non lo cancellerò. Ho alcuni vincoli su di me che hanno creato la necessità di una soluzione SQL pura. Devo ancora provare e testare la risposta di Stevo. Terrò il tuo qui se qualcuno ha bisogno di una soluzione come questa. +1 per il tuo interesse. Nel frattempo, assicurati di ottenere una soluzione basata solo su SQL.Sarà di grande aiuto. – Rachcha

0

Questa è la soluzione più elegante ho potuto venire con

WITH DirectTrades(tradeid, SourceDate, EndDate, Volume, Row, KillRow, Depth) AS 
(
    SELECT tradeid 
      BegDate AS SourceDate, 
      EndDate, 
      Volume, 
      ROW_NUMBER() over (partition by Table# order by BegDate) AS Row, 
      ROW_NUMBER() over (partition by Table# order by BegDate) AS KillRow, 
      0 AS Depth 
    FROM Trade 
    UNION ALL 
    SELECT t1.Tradeid 
      dt.SourceDate, 
      t1.EndDate, 
      t1.Volume, 
      dt.Row, 
      dt.Row + dt.Depth + 1, 
      dt.Depth + 1 
    FROM Trade AS t1 
      INNER JOIN 
      DirectTrades AS dt ON 
        t1.BegDate=dt.EndDate AND 
        t1.Volume=dt.Volume AND 
        t1.tradeid=dt.Tradeid 
) 

SELECT dt1.Tradeid 
     dt1.SourceDate, 
     dt1.EndDate, 
     dt1.Volume 
FROM DirectTrades dt1 
     INNER JOIN 
     (
     SELECT dt2.Row, 
       MAX(dt2.KillRow) AS KillRow 
     FROM DirectTrades dt2 
     WHERE dt2.Row NOT IN 
       (
       SELECT dt3.KillRow 
       FROM DirectTrades dt3 
       WHERE dt3.Depth <> 0 
       ) 
     GROUP BY dt2.Row 
     ) dt4 ON dt1.Row=dt4.Row AND dt1.KillRow=dt4.KillRow 
ORDER BY SourceDate 
+0

Non funziona. Ho il nome della tabella 'TRADE (TRADEID, BEGDATE, ENDDATE, VOLUME)' con i dati come descritto nella domanda. Fornisci gentilmente una soluzione conforme allo schema e modifica di conseguenza la tua risposta. – Rachcha

Problemi correlati