Crystal Reports Need to Group by Derived Date Range

后端 未结 4 1708
迷失自我
迷失自我 2020-12-18 06:58

Long time listner, first time caller. I\'m using Crystal Reports 2010.

I have daily trade information that I need to group together if the volume doesn\'t change. H

相关标签:
4条回答
  • 2020-12-18 06:59

    I'd use the "X-2" suppression function to hide all but the last from each row, and Previous() and Next() to find the endpoints.

    Group by BegDate; suppressing the details and group footer sections.

    Create an {@UpdateCurrentBegDate} function somewhere in the group header

    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
    

    And a {@DisplayBegDate} function where you currently have BegDate being shown

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

    Go to the Section Expert and click "X-2" next to the Suppress option (for the group header section). This is the formula for there

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

    If you need to do totals or other calculations, you would do it in the {@UpdateCurrentBegDate} function (and you'd want to change the name to {@UpdateCurrentValues} or something similar). You can also create a new function that checks the Next() information if you only want to change things when the group changes -- using the default totalling functions will include the hidden values.

    0 讨论(0)
  • 2020-12-18 07:02
    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 讨论(0)
  • 2020-12-18 07:04
    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 讨论(0)
  • 2020-12-18 07:22

    This is the most elegant solution I could come up with

    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 讨论(0)
提交回复
热议问题