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

một truy vấn tổng hợp với một số lưới logic bằng Oracle SQL

Tôi biết đây là một câu hỏi cũ và sẽ không có ích cho áp phích gốc, nhưng tôi muốn bắt đầu câu hỏi này vì nó là một câu hỏi thú vị. Tôi đã không kiểm tra nó đủ, vì vậy tôi hy vọng điều này vẫn cần được sửa chữa và điều chỉnh. Nhưng tôi tin rằng cách tiếp cận là hợp pháp. Tôi không khuyên bạn nên sử dụng một truy vấn như thế này trong một sản phẩm vì nó sẽ khó duy trì hoặc khó hiểu (và tôi không tin rằng điều này thực sự có thể mở rộng). Bạn sẽ tốt hơn nhiều nếu tạo một số cấu trúc dữ liệu thay thế. Phải nói rằng, đây là những gì tôi đã chạy trong Postgresql 9.1:

    WITH x AS (
        SELECT round, action
              ,ABS(shares) AS shares
              ,profitpershare
              ,COALESCE( SUM(shares) OVER(ORDER BY round, action
                                          ROWS BETWEEN UNBOUNDED PRECEDING 
                                                   AND 1 PRECEDING)
                        , 0) AS previous_net_shares
              ,COALESCE( ABS( SUM(CASE WHEN action = 'SELL' THEN shares ELSE 0 END)
                            OVER(ORDER BY round, action
                                     ROWS BETWEEN UNBOUNDED PRECEDING 
                                              AND 1 PRECEDING) ), 0 ) AS previous_sells
          FROM AuctionResults
          ORDER BY 1,2
    )

    SELECT round, shares * profitpershare - deduction AS net
      FROM (

           SELECT buy.round, buy.shares, buy.profitpershare
                 ,SUM( LEAST( LEAST( sell.shares, GREATEST(buy.shares - (sell.previous_sells - buy.previous_sells), 0)
                                    ,GREATEST(sell.shares + (sell.previous_sells - buy.previous_sells) - buy.previous_net_shares, 0)
                                   )
                             ) * sell.profitpershare ) AS deduction
             FROM x buy
                 ,x sell
             WHERE sell.round > buy.round
               AND buy.action = 'BUY'
               AND sell.action = 'SELL'
             GROUP BY buy.round, buy.shares, buy.profitpershare

           ) AS y

Và kết quả:

     round | net
    -------+-----
         1 | 780
         2 | 420
    (2 rows)

Để chia nó thành nhiều phần, tôi bắt đầu với tập dữ liệu này:

    CREATE TABLE AuctionResults( round int, action varchar(4), shares int, profitpershare int);

    INSERT INTO AuctionResults VALUES(1, 'BUY', 6, 200);
    INSERT INTO AuctionResults VALUES(2, 'BUY', 5, 100);
    INSERT INTO AuctionResults VALUES(2, 'SELL',-2, 50);
    INSERT INTO AuctionResults VALUES(3, 'SELL',-5, 80);
    INSERT INTO AuctionResults VALUES(4, 'SELL', -4, 150);  

    select * from auctionresults;

     round | action | shares | profitpershare
    -------+--------+--------+----------------
         1 | BUY    |      6 |            200
         2 | BUY    |      5 |            100
         2 | SELL   |     -2 |             50
         3 | SELL   |     -5 |             80
         4 | SELL   |     -4 |            150
    (5 rows)

Truy vấn trong mệnh đề "VỚI" thêm một số tổng đang chạy vào bảng.

  • "before_net_shares" cho biết số lượng cổ phiếu có sẵn để bán trước kỷ lục hiện tại. Điều này cũng cho tôi biết tôi cần bỏ qua bao nhiêu cổ phiếu "BÁN" trước khi có thể bắt đầu phân bổ nó cho "MUA" này.
  • "before_sells" là tổng số lượt chia sẻ "SELL" gặp phải, do đó, sự khác biệt giữa hai "before_sells" cho biết số lượt chia sẻ 'SELL' được sử dụng trong thời gian đó.

     round | action | shares | profitpershare | previous_net_shares | previous_sells
    -------+--------+--------+----------------+---------------------+----------------
         1 | BUY    |      6 |            200 |                   0 |              0
         2 | BUY    |      5 |            100 |                   6 |              0
         2 | SELL   |      2 |             50 |                  11 |              0
         3 | SELL   |      5 |             80 |                   9 |              2
         4 | SELL   |      4 |            150 |                   4 |              7
    (5 rows)
    

Với bảng này, chúng ta có thể tự tham gia trong đó mỗi bản ghi "MUA" được liên kết với mỗi bản ghi "BÁN" trong tương lai. Kết quả sẽ như thế này:

    SELECT buy.round, buy.shares, buy.profitpershare
          ,sell.round AS sellRound, sell.shares AS sellShares, sell.profitpershare AS sellProfitpershare
      FROM x buy
          ,x sell
      WHERE sell.round > buy.round
        AND buy.action = 'BUY'
        AND sell.action = 'SELL'

     round | shares | profitpershare | sellround | sellshares | sellprofitpershare
    -------+--------+----------------+-----------+------------+--------------------
         1 |      6 |            200 |         2 |          2 |                 50
         1 |      6 |            200 |         3 |          5 |                 80
         1 |      6 |            200 |         4 |          4 |                150
         2 |      5 |            100 |         3 |          5 |                 80
         2 |      5 |            100 |         4 |          4 |                150
    (5 rows)

Và sau đó là phần điên rồ cố gắng tính toán số lượng cổ phiếu có sẵn để bán theo thứ tự so với số lượng cổ phiếu chưa được bán để mua. Dưới đây là một số lưu ý để giúp làm theo điều đó. Các lệnh gọi "lớn nhất" với "0" chỉ nói rằng chúng ta không thể phân bổ bất kỳ cổ phiếu nào nếu chúng ta đang ở mức âm.

   -- allocated sells 
   sell.previous_sells - buy.previous_sells

   -- shares yet to sell for this buy, if < 0 then 0
   GREATEST(buy.shares - (sell.previous_sells - buy.previous_sells), 0)

   -- number of sell shares that need to be skipped
   buy.previous_net_shares

Cảm ơn David vì hỗ trợ




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dữ liệu mẫu - Sự cố khi thực hiện thủ tục được lưu trữ bao gồm cả câu lệnh cập nhật và chèn

  2. Gọi đến hàm không xác định oci_connect, php_oci8_12c.dll, windows 8.1, php5.6.6

  3. Cách tốt nhất để chèn hàng loạt dữ liệu vào cơ sở dữ liệu Oracle

  4. Giải nén Oracle từ giá trị cắt xml

  5. Hàm RPAD () trong Oracle