2012-10-23 35 views
5

Người nghe thời gian dài, người gọi lần đầu tiên. Tôi đang sử dụng Crystal Reports 2010.Báo cáo tinh thể cần nhóm theo Phạm vi ngày có nguồn gốc

Tôi có thông tin giao dịch hàng ngày mà tôi cần nhóm với nhau nếu khối lượng không thay đổi. Đây là dữ liệu trông như thế nào.

Triển # BegDate EndDate Khối lượng

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 

tôi cần nó trông như thế này.

Triển # datarange Khối lượng

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 

tôi cần phải nhóm bởi các phạm vi ngày có nguồn gốc nhưng tôi không chắc chắn làm thế nào để thực hiện điều này với Crystal. Bất kỳ ý tưởng ??

+0

tôi nghĩ rằng câu hỏi này cũng tương tự như http://stackoverflow.com/questions/13269569/drive-enddate-of -current-row-from-stardate-of-next-row/13418153 # 13418153 – WKordos

Trả lời

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 Kết quả sai, tên biến kém. –

+0

hoạt động nhưng không dễ hiểu và do đó không thể sao chép được. +1 chỉ để bạn quan tâm. – 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

Hoạt động một cách hoàn hảo, có vẻ như tối thiểu có thể viết mã để hoàn thành công việc. Vẫn đang tìm kiếm thêm giải pháp. +1. – Rachcha

+0

Câu trả lời hay nhất và nhỏ gọn nhất mà tôi có. Cảm ơn! +50. – Rachcha

1

Tôi muốn sử dụng "X-2" chức năng ức chế để ẩn tất cả nhưng cuối cùng từ mỗi hàng, và trước() và Next() để tìm ra điểm cuối.

Nhóm của BegDate; đàn áp các chi tiết và phần chân trang nhóm.

Tạo một {} @UpdateCurrentBegDate chức năng ở đâu đó trong tiêu đề nhóm

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 

Và một {} @DisplayBegDate chức năng mà bạn hiện đã BegDate được hiển thị

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

Chuyển đến mục Expert và nhấp vào "X-2" bên cạnh tùy chọn Suppress (cho phần tiêu đề nhóm). Đây là công thức cho có

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

Nếu bạn cần làm tổng số hoặc các tính toán khác, bạn sẽ làm điều đó trong {} @UpdateCurrentBegDate chức năng (và bạn muốn thay đổi tên để {} hoặc @UpdateCurrentValues một cái gì đó tương tự). Bạn cũng có thể tạo một hàm mới để kiểm tra thông tin Next() nếu bạn chỉ muốn thay đổi mọi thứ khi nhóm thay đổi - bằng cách sử dụng các hàm tổng cộng mặc định sẽ bao gồm các giá trị ẩn.

+0

Tuyệt vời, tôi không thấy "Tôi cần một giải pháp SQL thuần túy" cho đến khi sau khi đăng bài này. Tôi sẽ không xóa nó mặc dù nó trả lời câu hỏi gốc. – EvilBob22

+0

Cảm ơn câu trả lời của bạn. Thậm chí tôi sẽ không xóa nó. Tôi có một số ràng buộc đối với tôi đã tạo ra một nhu cầu cho một giải pháp SQL thuần túy. Tôi chưa thử và kiểm tra câu trả lời của Stevo. Tôi sẽ giữ nó ở đây nếu ai đó cần một giải pháp như thế này. 1 cho sự quan tâm của bạn. Trong khi đó, hãy xem nó mà bạn nhận được một giải pháp chỉ dựa trên SQL.Điều đó sẽ giúp ích rất nhiều. – Rachcha

0

Đây là giải pháp thanh lịch nhất mà tôi có thể đưa ra

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

Không hoạt động. Tôi có tên bảng 'TRADE (TRADEID, BEGDATE, ENDDATE, VOLUME)' với dữ liệu như mô tả trong câu hỏi. Vui lòng cung cấp giải pháp phù hợp với giản đồ và chỉnh sửa câu trả lời của bạn cho phù hợp. – Rachcha

Các vấn đề liên quan