2012-05-21 26 views
5

Tôi có một bảng chứa các giao dịch chứng khoán:truy vấn SQL để hiển thị những thay đổi để "tổng" cột

+------+----------------------+------------------+ 
| Item | Running Stock Total | Transaction Time | 
+------+----------------------+------------------+ 
| foo | 4     | 2012-05-12 11:07 | 
| bar | 3     | 2012-05-12 10:42 | 
| bar | 3     | 2012-05-12 9:42 | 
| bar | 2     | 2012-05-11 15:42 | 
| foo | 3     | 2012-05-11 10:02 | 
| bar | 3     | 2012-05-10 13:44 | 
...etc... 
+------+----------------------+------------------+ 

tức Bất cứ lúc nào một cái gì đó xảy ra với chứng khoán, một hàng được tạo ra trong Bảng- này này có thể có nghĩa là chứng khoán mức tăng (cổ phiếu mới đã ra lệnh), giảm (bán cổ phiếu) hoặc không thay đổi (cổ phiếu di dời).

Tôi cần phải tạo truy vấn sql chỉ trả lại các hàng mà cấp độ cổ phiếu đã thực sự thay đổi cho một phần cụ thể và cần hiển thị các thay đổi trong cột "stock up" và "stock down".

ví dụ: 1 Item='bar'

+------+-----------+------------+----------------------+------------------+ 
| Item | Stock Up | Stock Down | Running Stock Total | Transaction Time | 
+------+-----------+------------+----------------------+------------------+ 
| bar |  1 |  0  | 3     | 2012-05-12 9:42 | 
| bar |  0 |  1  | 2     | 2012-05-11 15:42 | 
| bar |  1 |  0  | 3     | 2012-05-10 13:44 | 
+------+-----------+------------+----------------------+------------------+ 

e.g.2 Item='foo'

+------+-----------+------------+----------------------+------------------+ 
| Item | Stock Up | Stock Down | Running Stock Total | Transaction Time | 
+------+-----------+------------+----------------------+------------------+ 
| foo |  1 |  0  | 4     | 2012-05-12 11:07 | 
| foo |  2 |  0  | 3     | 2012-05-11 10:02 | 
+------+-----------+------------+----------------------+------------------+ 

Vì vậy, một cái gì đó giống như ...

SELECT 
    Item, {xyz} as 'Stock Up', {abc} as 'Stock Down', `Running Stock Total`, `Transaction Time` 
FROM 
    `StockTransactions` 
WHERE 
    `Item`='foo' 
HAVING 
    ('Stock Up'>0 or 'Stock Down'>0) 

này có thể được thực hiện?

+0

Bạn phân biệt khi nào cổ phiếu tăng và khi cổ phiếu giảm? – JHS

+0

Bằng cách sử dụng "Tổng số chứng khoán đang chạy" – Urbycoz

+0

Cú pháp của bạn trông giống như SQL Server, nhưng câu hỏi của bạn được gắn thẻ MySQL. Bạn đang sử dụng cái nào? – eggyal

Trả lời

3
SELECT `Item`, 
     `Stock Up`, 
     `Stock Down`, 
     `Running Stock Total`, 
     `Transaction Time` 

FROM (
    SELECT `Item`, 
      GREATEST(`Running Stock Total` - @`last_total`, 0) AS `Stock Up`, 
      GREATEST(@`last_total` - `Running Stock Total`, 0) AS `Stock Down`, 
      `Running Stock Total`, 
      `Transaction Time`, 
      @`last_total` := `Running Stock Total` 
    FROM  `StockTransactions` JOIN (SELECT @`last_total` := 0) AS lt 
    WHERE `Item` = 'bar' 
    ORDER BY `Transaction Time` ASC 
) AS t 

ORDER BY `Transaction Time` DESC 

Xem trên sqlfiddle. Các truy vấn bên ngoài rõ ràng có thể được bỏ qua nếu bạn đang hạnh phúc cho các kết quả được sắp xếp theo thứ tự tăng dần của thời gian giao dịch và với thêm last_total cột.

+1

Truy vấn bên ngoài không thể bỏ qua, vì nó nằm trong truy vấn bên ngoài mà các hàng có thể (và phải) được lọc trên điều kiện ''Stock Up'> 0 hoặc 'Stock Down'> 0' (được yêu cầu bởi câu hỏi và bạn không làm gì). Ngoài ra, tôi nghĩ giải pháp của bạn sẽ hoạt động. –

+0

@eggyal Đây là một giải pháp tuyệt vời và thanh lịch. Cảm ơn bạn! – Urbycoz

+0

@AndriyM: Điểm tốt - tôi đã bỏ qua yêu cầu đó. – eggyal

0

Một giải pháp có thể là:

  1. Thực hiện một con trỏ để chọn từng dòng một lúc
  2. Kiểm tra nếu giá trị thay đổi và nếu như vậy, chèn các thông tin trong một bảng #temp
  3. Chọn tất cả dữ liệu từ bảng #temp

Thay vì con trỏ, bạn có thể sử dụng chu kỳ trong khi bạn có thể xác định tất cả các hàng liên tiếp.

0

Tôi sẽ thử một cái gì đó như đặt biến chứa giá cổ phiếu cũ. Đầu tiên, sắp xếp bảng theo từng mục để bạn có thể tự giải quyết tất cả dữ liệu cho từng cổ phiếu.

Sau đó, bạn có thể nói điều gì đó như int counter = 0; decimal startingPrice = 0; chi phí thập phân = 0;

 var list = new List<Decimal>(); 
     Decimal[] positivePercentagesToTest = new Decimal[] { 1.02m, 1.03m, 1.04m, 1.10m, 100 }; 
     Decimal[] negativePercentagesToTest = new Decimal[] { 0.99m, 0.985m, 0.98m, 0.95m, 0.9m }; 

     for (int i = 0; i <= positivePercentagesToTest.Count() -1 ;i++) 
     { 
      foreach (var s in stocks) 
      { 
       //if(s.Ticker == "BAC") 
       { 
        if (counter == 0) 
        { 
         startingPrice = s.Open; 
        } 
        counter++; 

        var openPrice = s.Open; 

        if (openPrice > (startingPrice * positivePercentagesToTest[i]) || openPrice < (startingPrice * negativePercentagesToTest[i])) 
        { 
         //sell 
         //same as percentage gain 
         var percentage = openPrice/startingPrice - 1; 

         list.Add(Math.Round(percentage, 2)); 
         counter = 0; 
        } 

       } 

      } 

      var amount = list.Sum(); 
      var profitToAdd = new Profits(); 
      profitToAdd.Amount = amount; 

Đây là mã C#. Nếu bạn cần nó trong sql, cho tôi biết. Đây chỉ là logic tôi sẽ sử dụng.

+0

Tôi sợ rằng tôi cần nó trong sql. – Urbycoz

0

Tôi không biết hương vị SQL của bạn, nhưng trong Oracle có LAG()LEAD() chức năng phân tích cho phép bạn truy cập các giá trị cột từ hàng trước hoặc tiếp theo trong tập kết quả. Bạn có thể sử dụng LAG() để xem sự khác biệt giữa kết quả trước đó và kết quả hiện tại và quyết định xem có lên hay xuống. Có bất cứ điều gì tương tự trong SQL của bạn?

+0

Tôi đang sử dụng MySQL. Đừng nghĩ rằng nó có bất cứ điều gì tương tự. – Urbycoz

1

Giải pháp của tôi hoạt động dựa trên giả thiết, rằng Transaction Time là duy nhất cho mỗi Item.

Tôi mô phỏng row_number() chức năng phân tích thông qua view helper mà tôi tạo ra:

CREATE VIEW running_stock AS 
SELECT s.item,s.running_total,s.transaction_dt, 
    (SELECT count(*) FROM stock WHERE item=s.item 
     AND transaction_dt <= s.transaction_dt) AS row_number 
    FROM stock s 
ORDER BY 1, 4; 

Sau khi xem được đặt ra, bạn có thể có được kết quả mong muốn với các truy vấn sau đây:

SELECT c.item AS "Item", 
    greatest(c.running_total - p.running_total, 0) AS "Stock Up", 
    greatest(p.running_total - c.running_total, 0) AS "Stock Down", 
    c.running_total AS "Running Total", 
    c.transaction_dt AS "Transaction Time" 
FROM running_stock c 
LEFT JOIN running_stock p ON c.item = p.item 
     AND p.row_number + 1 = c.row_number 
WHERE c.row_number > 1 
ORDER BY 1, 5; 

Bạn có thể chơi với truy vấn này trên SQL Fiddle.

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