2012-05-21 55 views
5

我有一個包含股票的交易表:SQL查詢來顯示更改爲「總計」列

+------+----------------------+------------------+ 
| 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... 
+------+----------------------+------------------+ 

即任何時候有事股票,排在該表 - 創建,這可能意味着股票水平上漲(訂購新股票),下跌(股票賣出)或保持不變(股票重新定位)。

我需要創建一個sql查詢,該查詢僅返回庫存級別實際上已更改爲某個特定部分的行,並且需要顯示「庫存增加」和「庫存減少」列中的更改。

即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 | 
+------+-----------+------------+----------------------+------------------+ 

所以像...

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) 

可以這樣做?

+0

如何區分股票何時上漲以及股票何時下跌? – JHS

+0

通過使用「Running Stock Total」 – Urbycoz

+0

您的語法看起來像SQL Server,但您的問題被標記爲MySQL。你在用哪個? – eggyal

回答

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 

請參閱sqlfiddle。如果你高興的結果,在上升的交易時間順序並使用額外last_total列進行排序的外部查詢顯然可以省略。

+1

外部查詢不能省略,因爲在外部查詢中,行可以(並且必須)在「'Stock Up'> 0或'Stock Down'> 0」條件下過濾(問題需要而你沒有做的)。除此之外,我認爲你的解決方案應該工作。 –

+0

@eggyal這是一個優秀和優雅的解決方案。謝謝! – Urbycoz

+0

@AndriyM:好點 - 我忽略了這個要求。 – eggyal

0

一種解決方案可能是:

  1. 讓光標在一次選擇每行
  2. 檢查值發生變化,如果是這樣,在#temp表
  3. 選擇插入的所有信息來自#temp表的數據

如果您可以按順序識別所有行,則可以使用while循環代替遊標。

0

我會嘗試像設置包含舊股票價格的變量。首先逐個對產品進行排序,以便您可以自行處理每種產品的所有數據。

然後,你可以這樣說 INT計數器= 0; decimal startingPrice = 0; 十進制代價= 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; 

這是C#代碼。如果你在sql中需要它,讓我知道。這只是我使用的邏輯。

+0

恐怕我確實需要它在SQL中。 – Urbycoz

0

我不知道您的SQL風格,但在Oracle中有LAG()LEAD()分析函數,它們允許您訪問結果集中上一行或下一行的列值。您可以使用LAG()來查看以前和當前結果之間的差異,並確定是否已啓動或關閉。你的SQL中有沒有類似的東西?

+0

我正在使用MySQL。不要以爲它有類似的東西。 – Urbycoz

1

我的解決辦法的作品基於一個假設,即Transaction TimeItem獨特。

我通過助手視圖模擬row_number()分析功能,我創建:

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; 

的觀點是到位後,可以得到與下面的查詢所需的結果:

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; 

你可以在SQL Fiddle上玩這個查詢。