Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Tích lũy thêm dữ liệu còn thiếu từ tháng trước hoặc năm trước

Một biến thể của phương pháp @boneists, bắt đầu với dữ liệu mẫu của bạn trong CTE:

with t as (
  select 1 id, 'A' name, '2007' year, '04' month,  5 sales  from dual union all
  select 2 id, 'A' name, '2007' year, '05' month,  2 sales  from dual union all
  select 3 id, 'B' name, '2008' year, '12' month,  3 sales  from dual union all
  select 4 id, 'B' name, '2009' year, '12' month, 56 sales  from dual union all
  select 5 id, 'C' name, '2009' year, '08' month, 89 sales  from dual union all
  select 13 id,'B' name, '2016' year, '01' month, 10 sales  from dual union all
  select 14 id,'A' name, '2016' year, '02' month,  8 sales  from dual union all
  select 15 id,'D' name, '2016' year, '03' month, 12 sales  from dual union all
  select 16 id,'E' name, '2016' year, '04' month, 34 sales  from dual
),
y (year, rnk) as (
  select year, dense_rank() over (order by year)
  from (select distinct year from t)
),
r (name, year, month, sales, rnk) as (
  select t.name, t.year, t.month, t.sales, y.rnk
  from t
  join y on y.year = t.year
  union all
  select r.name, y.year, r.month, 0, y.rnk
  from y
  join r on r.rnk = y.rnk - 1
  where not exists (
    select 1 from t where t.year = y.year and t.month = r.month and t.name = r.name
  )
)
select name, year, month, sales,
  nvl(sum(sales) over (partition by name order by year, month
    rows between unbounded preceding and 1 preceding), 0) as opening_bal,
  nvl(sum(sales) over (partition by name order by year, month
    rows between unbounded preceding and current row), 0) as closing_bal
from r
order by year, month, name;

Điều nào cũng nhận được kết quả tương tự, mặc dù nó cũng không khớp với kết quả mong đợi trong câu hỏi:

NAME YEAR MONTH      SALES OPENING_BAL CLOSING_BAL
---- ---- ----- ---------- ----------- -----------
A    2007 04             5           0           5
A    2007 05             2           5           7
A    2008 04             0           7           7
A    2008 05             0           7           7
B    2008 12             3           0           3
A    2009 04             0           7           7
A    2009 05             0           7           7
C    2009 08            89           0          89
B    2009 12            56           3          59
B    2016 01            10          59          69
A    2016 02             8           7          15
D    2016 03            12           0          12
A    2016 04             0          15          15
E    2016 04            34           0          34
A    2016 05             0          15          15
C    2016 08             0          89          89
B    2016 12             0          69          69

y CTE (vui lòng sử dụng các tên có ý nghĩa hơn!) Tạo ra tất cả các năm khác biệt với dữ liệu ban đầu của bạn và cũng thêm xếp hạng, vì vậy 2007 là 1, 2008 là 2, 2009 là 3 và 2016 là 4.

r CTE đệ quy kết hợp dữ liệu thực tế của bạn với các hàng giả không có doanh số bán hàng, dựa trên dữ liệu tên / tháng từ những năm trước.

Từ những gì mà CTE đệ quy tạo ra, bạn có thể tính tổng tích lũy phân tích của mình để thêm số dư mở / đóng. Điều này đang sử dụng các mệnh đề cửa sổ để quyết định giá trị bán hàng nào cần bao gồm - về cơ bản số dư mở và đóng là tổng của tất cả các giá trị cho đến thời điểm này, nhưng việc mở không bao gồm hàng hiện tại.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Các biến PL / SQL trong con trỏ có hiệu quả giống như các tham số liên kết không?

  2. Cách hiển thị ngày ở định dạng khác trong oracle

  3. Sử dụng Oracle kết hợp ba bảng thành một với PIVOT

  4. Oracle UTL_SMTP:Ví dụ về Gửi Thư với Phần đính kèm Sử dụng Xác thực Ví Oracle

  5. ORA-28001:Mật khẩu đã hết hạn