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

Làm cách nào để lấy sự kiện “tiếp theo” khi giá trị thay đổi đối với các mục có thể được xử lý nhiều lần?

Đây là một vấn đề về khoảng trống và các đảo, nhưng các đảo đang được xác định bởi một REQ giao dịch làm cho nó phức tạp hơn một chút so với một số.

Bạn có thể sử dụng các hàm dẫn và độ trễ lồng nhau và một số thao tác để có được những gì bạn cần:

select distinct item,
  coalesce(start_tran,
    lag(start_tran) over (partition by item order by timestamp)) as start_tran,
  coalesce(end_tran,
    lead(end_tran) over (partition by item order by timestamp)) as end_tran,
  coalesce(end_time, 
    lead(end_time) over (partition by item order by timestamp))
    - coalesce(start_time,
        lag(start_time) over (partition by item order by timestamp)) as time
from (
  select item, timestamp, start_tran, start_time, end_tran, end_time
  from (
    select item,
      timestamp,
      case when lag_tran is null or transaction like 'REQ%'
        then transaction end as start_tran,
      case when lag_tran is null or transaction like 'REQ%'
        then timestamp end as start_time,
      case when lead_tran is null or lead_tran like 'REQ%'
        then transaction end as end_tran,
      case when lead_tran is null or lead_tran like 'REQ%'
        then timestamp end as end_time
    from (
      select item, transaction, timestamp,
        lag(transaction)
          over (partition by item order by timestamp) as lag_tran,
        lead(transaction)
          over (partition by item order by timestamp) as lead_tran
      from transactions
    )
  )
  where start_tran is not null or end_tran is not null
)
order by item, start_tran;

Với các bản ghi bổ sung cho chu kỳ thứ hai cho các mục 1 và 2 có thể cho:

      ITEM START_TRAN END_TRAN   TIME      
---------- ---------- ---------- -----------
         1 REQ-A      PICKUP     0 1:53:30.0 
         1 REQ-E      PICKUP     0 1:23:30.0 
         2 REQ-B      MAIL       0 0:24:13.0 
         2 REQ-F      REQ-F      0 0:0:0.0   
         3 REQ-C      PICKUP     0 1:46:30.0 
         4 REQ-D      PULL       0 0:23:59.0 
         5 REQ-A      PICKUP     0 1:43:59.0 

SQL Fiddle hiển thị tất cả các bước trung gian.

Nó không hoàn toàn đáng sợ như thoạt nhìn có thể thấy. Truy vấn trong cùng lấy dữ liệu thô và thêm một cột bổ sung cho các giao dịch khách hàng tiềm năng và giao dịch trễ. Chỉ lấy tập hợp các bản ghi mục-1 đầu tiên sẽ là:

      ITEM TRANSACTION TIMESTAMP                LAG_TRAN   LEAD_TRAN
---------- ----------- ------------------------ ---------- ----------
         1 REQ-A       2014-07-31T09:51:32Z                PULL       
         1 PULL        2014-07-31T10:22:21Z     REQ-A      TRANSFER   
         1 TRANSFER    2014-07-31T10:22:23Z     PULL       ARRIVE     
         1 ARRIVE      2014-07-31T11:45:01Z     TRANSFER   PICKUP     
         1 PICKUP      2014-07-31T11:45:02Z     ARRIVE     REQ-E      

Lưu ý REQ-E bật lên dưới dạng lead_tran cuối cùng ? Đó là transaction đầu tiên cho chu kỳ thứ hai của các bản ghi cho mục này và sẽ hữu ích sau này. Cấp độ truy vấn tiếp theo sử dụng các giá trị khách hàng tiềm năng và độ trễ đó và xử lý REQ các giá trị làm điểm đánh dấu bắt đầu và kết thúc, đồng thời sử dụng thông tin đó để xóa mọi thứ ngoại trừ bản ghi đầu tiên và bản ghi cuối cùng cho mỗi chu kỳ.

      ITEM TIMESTAMP                START_TRAN START_TIME               END_TRAN   END_TIME               
---------- ------------------------ ---------- ------------------------ ---------- ------------------------
         1 2014-07-31T09:51:32Z     REQ-A      2014-07-31T09:51:32Z                                         
         1 2014-07-31T10:22:21Z                                                                             
         1 2014-07-31T10:22:23Z                                                                             
         1 2014-07-31T11:45:01Z                                                                             
         1 2014-07-31T11:45:02Z                                         PICKUP     2014-07-31T11:45:02Z     

Cấp độ truy vấn tiếp theo sẽ xóa bất kỳ hàng nào không đại diện cho phần bắt đầu hoặc phần kết thúc (hoặc cả hai - xem REQ-F trong Fiddle) vì chúng tôi không quan tâm đến chúng:

      ITEM TIMESTAMP                START_TRAN START_TIME               END_TRAN   END_TIME               
---------- ------------------------ ---------- ------------------------ ---------- ------------------------
         1 2014-07-31T09:51:32Z     REQ-A      2014-07-31T09:51:32Z                                         
         1 2014-07-31T11:45:02Z                                         PICKUP     2014-07-31T11:45:02Z     

Bây giờ chúng ta có các cặp hàng cho mỗi chu kỳ (hoặc một hàng cho REQ-F ). Mức cuối cùng sử dụng chì và độ trễ một lần nữa để điền vào chỗ trống; nếu start_tran là null thì đây là hàng kết thúc và chúng ta nên sử dụng dữ liệu bắt đầu của hàng trước đó; nếu end_tran là null thì đây là hàng bắt đầu và chúng ta nên sử dụng dữ liệu kết thúc của hàng tiếp theo.

  ITEM START_TRAN START_TIME               END_TRAN   END_TIME                 TIME      
     1 REQ-A      2014-07-31T09:51:32Z     PICKUP     2014-07-31T11:45:02Z     0 1:53:30.0 
     1 REQ-A      2014-07-31T09:51:32Z     PICKUP     2014-07-31T11:45:02Z     0 1:53:30.0 

Điều đó làm cho cả hai hàng giống nhau, vì vậy distinct loại bỏ các bản sao.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle’s Containers cho J2EE (OC4J) trong R12

  2. Lỗi khi cố gắng truy xuất văn bản do lỗi ORA-01804

  3. Cấu hình Oracle OCI8 cho Windows 64 bit

  4. Thu thập hàng loạt vào và thực hiện ngay lập tức trong Oracle

  5. Sử dụng 'cột biểu thức chữ hoa chữ thường' trong mệnh đề where