5

長年のリスナー、初めての電話者。Crystal Reports 2010 を使用しています。

出来高が変化しない場合、グループ化する必要がある毎日の取引情報があります。データは次のようになります。

取引番号 BegDate EndDate 出来高

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

このように見える必要があります。

取引番号 日付範囲 出来高

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

派生した日付範囲でグループ化する必要がありますが、Crystal でこれを達成する方法がわかりません。何か案は??

4

4 に答える 4

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
于 2012-11-29T22:08:11.707 に答える
1

「X-2」抑制関数を使用して各行の最後の行を除くすべてを非表示にし、Previous() と Next() を使用してエンドポイントを見つけます。

BegDate でグループ化します。詳細およびグループ フッター セクションを非表示にします。

グループ ヘッダーのどこかに {@UpdateCurrentBegDate} 関数を作成します。

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

そして、現在 BegDate が表示されている {@DisplayBegDate} 関数

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

セクション エキスパートに移動し、[抑制] オプションの横にある [X-2] をクリックします (グループ ヘッダー セクションの場合)。これはそこでの式です

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

合計やその他の計算を行う必要がある場合は、{@UpdateCurrentBegDate} 関数で行います (名前を {@UpdateCurrentValues} などに変更します)。グループが変更されたときにのみ変更したい場合は、Next() 情報をチェックする新しい関数を作成することもできます。デフォルトの合計関数を使用すると、非表示の値が含まれます。

于 2012-11-29T23:57:24.550 に答える
0

これは私が思いつくことができる最もエレガントなソリューションです

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
于 2012-11-30T20:29:39.740 に答える
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
于 2012-11-28T12:04:50.167 に答える