【发布时间】:2021-09-20 15:29:18
【问题描述】:
我正在尝试通过结合我对金融的兴趣来学习一些 SQL。目前我正在尝试根据交易列表(在 SQL Server 中)计算一些投资组合数据。
这是我的桌子:
create table StockTransactions
(
TransactionID int,
Instrument varchar(32),
TransactionType varchar(32),
Units int,
Price float,
TransactionSum as case
when TransactionType = 'Buy' then (-(Units * Price))
when TransactionType = 'Sell' then (Units * Price)
else 0
end,
PurchaseCost float
)
样本数据:
insert into StockTransactions (TransactionID, Instrument, TransactionType, Units, Price)
values
(1, 'Apple', 'Buy', 10, 120),
(2, 'Microsoft', 'Buy', 20, 290),
(3, 'Apple', 'Buy', 10, 125),
(4, 'Apple', 'Sell', 5, 140),
(5, 'Apple', 'Buy', 10, 130),
(6, 'Apple', 'Sell', 10, 135)
此表中的结果:
| TransactionID | Instrument | TransactionType | Units | Price | TransactionSum | PurchaseCost |
|---|---|---|---|---|---|---|
| 1 | Apple | Buy | 10 | 120 | -1200 | NULL |
| 2 | Microsoft | Buy | 20 | 290 | -5800 | NULL |
| 3 | Apple | Buy | 10 | 125 | -1250 | NULL |
| 4 | Apple | Sell | 5 | 140 | 700 | NULL |
| 5 | Apple | Buy | 10 | 130 | -1300 | NULL |
| 6 | Apple | Sell | 10 | 135 | 1350 | NULL |
我正在尝试计算 PurchaseCost 列的值。我想要的值是:
| Row | PurchaseCost |
|---|---|
| 1 | -1200 |
| 2 | -5800 |
| 3 | -2450 |
| 4 | -1837.5 |
| 5 | -3137.5 |
| 6 | -2353.13 |
逻辑如下。如果已进行购买,则应将 TransactionSum 添加到该工具的最新先前 PurchaseCost。但是,当进行销售时,应该减去一定的金额。
在第四次交易中,我卖出了 20 股 Apple 股票中的 5 股。因此,我想减去之前 PurchaseCost 的 1/4,得到新的 PurchaseCost 值 -1837.5。
在交易 6 中,我卖出了 25 股 Apple 股票中的 10 股,然后想将 PurchaseCost 降低到 2353.13(之前价值的 60%)。
我自己似乎无法弄清楚如何做到这一点。有什么想法吗?
【问题讨论】:
-
仅供参考,对于名为
Price的列,数据类型float是一个糟糕的选择。货币价值应该永远存储为浮点数。 -
看起来
PurchaseCost是一个运行总值。如果是这样,那不属于表格,最好在VIEW中提供。 -
也许可以从this 得到答案,除非您似乎在寻找 FIFO 而不是 LIFO
-
您的表格也需要一个日期(可能还需要一个时间部分)——您应该重新考虑派生成本的会计逻辑,以便计算利润(或收入或您想要应用的任何术语)。在现实世界中,人们对旧交易进行长期修正,并在旧交易中添加新交易。如果打算将其用作真正的生产就绪系统,那么您当前的路径过于简单。
-
感谢您的建议! Larnu:我将在我的数据库中更改 Price 的名称,并查看视图以了解它们如何在这种情况下使用。 SteveC:实际上在我的国家,我们使用平均成本而不是先进先出或后进先出。所以每次购买(只要我有职位)都会产生影响。 (这在报税季会很烦人。)
标签: sql sql-server