我有一张包含股票交易的表格:
+------+----------------------+------------------+
| 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 |
+------+-----------+------------+----------------------+------------------+
例如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 :(得分: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 :(得分: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 Fiddle上播放此查询。
答案 2 :(得分:0)
一种解决方案可能是:
如果您可以按顺序识别所有行,则可以使用while循环代替游标。
答案 3 :(得分:0)
我会尝试设置包含旧股票价格的变量。首先按项目排序,以便您可以自己处理每个库存的所有数据。
然后你可以这样说 int counter = 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中,请告诉我。这只是我会使用的逻辑。
答案 4 :(得分:0)
我不知道您的SQL风格,但在Oracle中有LAG()
和LEAD()
分析函数,允许您从结果集中的上一行或下一行访问列值。您可以使用LAG()
查看先前和当前结果之间的差异,并确定是上升还是下降。你的SQL中有类似的东西吗?