5

株式取引を含むテーブルがあります。

+------+----------------------+------------------+
| 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クエリを作成する必要があり、「在庫あり」列と「在庫減少」列に変更を表示する必要があります。

すなわち1Item='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 |
+------+-----------+------------+----------------------+------------------+

eg2Item='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)

これはできますか?

4

5 に答える 5

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列を使用して並べ替えられることに満足している場合は、外部クエリを明らかに省略できます。

于 2012-05-21T11:19:20.770 に答える
1

Transaction Time私のソリューションは、ごとに一意であるという仮定に基づいて機能しItemます。

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フィドルでこのクエリを試すことができます。

于 2012-05-21T11:40:38.107 に答える
0

1つの解決策は次のとおりです。

  1. カーソルを作成して、一度に各行を選択します
  2. 値が変更されたかどうかを確認し、変更された場合は、#tempテーブルに情報を挿入します
  3. #tempテーブルからすべてのデータを選択します

すべての行を順番に識別できる場合は、カーソルの代わりにwhileサイクルを使用できます。

于 2012-05-21T10:58:42.067 に答える
0

古い株価を含む変数を設定するようなものを試してみます。まず、テーブルをアイテムごとに並べ替えて、各株式のすべてのデータを単独で処理できるようにします。

次に、int counter=0のように言うことができます。10進数のstartingPrice=0; 10進数のコスト=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で必要な場合は、お知らせください。これは私が使用するロジックです。

于 2012-05-21T11:06:39.637 に答える
0

SQLのフレーバーはわかりませんが、Oracleには、結果セットの前または次の行の列値にアクセスできる分析関数がLAG()あります。以前の結果と現在の結果の違いを確認し、が上か下かを判断するためにLEAD()使用できます。LAG()SQLに似たようなものはありますか?

于 2012-05-21T11:12:17.263 に答える