【问题标题】:SQL to calculate value of Shares at a particular timeSQL 计算特定时间的 Shares 价值
【发布时间】:2013-04-08 12:34:47
【问题描述】:

我正在寻找一种方法来计算股票在给定时间的价值。

在示例中,我需要计算和报告给定月份的股票赎回情况。

我需要查看 3 个表格:

  1. 包含赎回日期、赎回股份数量和股份类型的赎回表。

  2. 共享类型表,具有共享类型并链接第 1 和第 3 个表。

  3. 包含股票类型、估值日期、价值的股价表。

所以我需要做的是报告并根据股票赎回次数计算这些股票按月细分的价值。

这有意义吗?

提前感谢您的帮助!

抱歉,我想我应该进一步详细说明,因为可能存在一些误解。这不是计算每日变化的股票和股票,更多的是为了基金管理。这意味着股价仅按月变动,而且通常也会滞后一个月。

这样做的效果是查询需要做的是查看兑换日期,计算出日期,即月份和年份。然后查看股价表,如果有给定日期的股价(这将需要计算,因为它将是一天,即价格是第 y 天的 x),然后将它们的单位数乘以这个值。但是,如果在给定日期没有股票价格,则使用该特定股票类型的最后价格。

希望这可能会更清楚一点,但如果我可以提供任何其他信息以使这更容易,请告诉我,我会为您提供信息。

问候,

菲尔

【问题讨论】:

  • 我不明白“共享类型”表是什么,也不明白为什么需要它。
  • @No'am Newman,如果其他两个表不包含特定 ShareType 的值,则需要它,但仍需要在报告中列出。
  • 另一张表的原因是因为一些赎回将在 1 月份,当时股价是一个值,然后在 2 月份,随着价格上涨,价格是一个不同的值,所以需要根据与记录赎回时间相关的价格(如果有意义的话)
  • 抱歉,我应该补充一点,股价仅每月更新一次。而且更新是追溯完成的,所以如果当前日期是 4 月,那么可能还没有 3 月份的股价,所以它需要查看 2 月份的价格,直到 2 月份的价格公布。

标签: sql sql-server sql-server-2008 tsql reporting-services


【解决方案1】:

这应该可以解决问题(注意:更新为按 ShareType 分组):

SELECT
   ST.ShareType,
   RedemptionMonth = DateAdd(month, DateDiff(month, 0, R.RedemptionDate), 0),
   TotalShareValueRedeemed = Sum(P.SharePrice * R.SharesRedeemed)
FROM
   dbo.Redemption R
   INNER JOIN dbo.ShareType ST
      ON R.ShareTypeID = ST.ShareTypeID
   CROSS APPLY (
      SELECT TOP 1 P.*
      FROM dbo.SharePrice P
      WHERE
         R.ShareTypeID = P.ShareTypeID
         AND R.RedemptionDate >= P.SharePriceDate
      ORDER BY P.SharePriceDate DESC
   ) P
GROUP BY
   ShareType,
   DateAdd(month, DateDiff(month, 0, R.RedemptionDate), 0)
ORDER BY
   ShareType,
   RedemptionMonth
;

See it working in a Sql Fiddle.

这可以通过简单地在Redemption 表上添加带有条件的 WHERE 子句来轻松参数化。如果您需要在没有赎回的月份中为共享类型显示 0,请告诉我,我会改进我的答案——如果您稍微填写一下您的用例场景并准确描述,这会有所帮助你想输入什么,你想看到什么输出。

另外请注意:我在这里假设股票赎回始终存在价格 - 如果赎回存在于任何股价之前,则该赎回将被排除在外。

【讨论】:

  • 差不多了,这实际上比我需要的更进一步和更好,如果这有道理的话!当我正在寻找用于报告目的的值时,我需要它在赎回表上逐行返回赎回现金值。
  • 在商业案例方面,我们有一个基金投资于英国的房地产。在该基金中,有来自世界各地的各种认购,因此我们有英镑、欧元、美元、大师和日元基金。每个基金都有自己的股价,因为它们成立的时间不同,投资的资产也不同,因此它们的股价也不同。
  • 投资者在 2007 年 1 月以 1.03 英镑的股价将资金存入基金,然后 5 年后他们赎回了他们的股票,价格为 1.90 英镑,他们正在赎回 10000 单位(股票) 然后它需要计算该赎回的价值。现在由于有赎回资金的通知期,我们将在 3 月初收到通知,通知正在赎回,但 3 月份的股价尚未确定
  • (股价是根据每个月评估的物业的净资产价值设定的)因此它需要具有基于最新股价的报告目的价值,直到该股价相关月份公布。这是否回答了用例场景?非常感谢您的帮助!!!我正在使用查询来获取数据,以便可以在 SQL 报告中生成报告。谢谢,菲尔
  • 糟糕...我最初发布时忘记按共享类型分组。我现在已经这样做了。那个更好吗?如果没有,请详细说明我的查询未提供所需结果的原因。
【解决方案2】:

如果您有每天的估值,那么计算是一个简单的联接,然后是一个聚合。结果查询类似于:

select year(redemptiondate), month(redemptiondate),
       sum(r.NumShares*sp.Price) as TotalPrice
from Redemptions r left outer join
     ShareType st
     on r.sharetype = st.sharetype left outer join
     SharePrice sp
     on st.sharename = sp.sharename and r.redemptiondate = sp.pricedate
group by year(redemptiondate), month(redemptiondate)
order by 1, 2;

【讨论】:

  • 不幸的是,我们没有每日估值,它是每月一次的,这让它变得有点复杂,通常会落后一个月,所以我们还需要考虑到最新的并使用这是相关月份的价格。
  • @Pipster1981:您应该将有关每月只有一个值的信息添加到您的问题中,因为它与答案非常相关。这也是完全不准确的——股票价格可能在一个月内变化 10%。
  • 我知道传统的股票价格可以,但是,这不是传统的股票价格,这是股价,基金的股价可以每月更新一次。
【解决方案3】:

如果我理解您的问题,您需要这样的查询

select shares.id, shares.name, sum (redemption.quant * shareprices.price)
from shares 
inner join redemption on shares.id = redemption.share
inner join shareprices on shares.id = shareprices.share
where redemption.curdate between :p1 and :p2
order by shares.id
group by shares.id, shares.name

:p1 和 :p2 是日期参数

【讨论】:

    【解决方案4】:

    如果您只需要一个日期范围:

    SELECT s.ShareType, SUM(ISNULL(sp.SharePrice, 0) * ISNULL(r.NumRedemptions, 0)) [RedemptionPrice]
    FROM dbo.Shares s   
    LEFT JOIN dbo.Redemptions r
        ON r.ShareType = s.ShareType
    OUTER APPLY (
        SELECT TOP 1 SharePrice
        FROM dbo.SharePrice p
        WHERE p.ShareType = s.ShareType
        AND p.ValuationDate <= r.RedemptionDate
        ORDER BY p.ValuationDate DESC) sp
    WHERE r.RedemptionDate BETWEEN @Date1 AND @Date2
    GROUP BY s.ShareType
    

    @Date1 和@Date2 是您的日期

    ISNULL 检查就在那里,因此如果某些内容为空(它将为 0),它实际上会为您提供一个值。在这种情况下,它是完全可选的,只是个人喜好。

    OUTER APPLY 的作用类似于LEFT JOIN,它将过滤来自 SharePrice 的结果,以确保您从基于 RedemptionDate 的表中获得最新的 ValuationDate,即使它与该日期范围不同日期。它可能可以通过另一种方式实现,但我觉得这很容易阅读。

    如果您对 OUTER APPLY 不满意,您可以在 SELECT 部分使用子查询(即ISNULL(r.NumRedemptions, 0) * (/* subquery from dbo.SharePrice here */)

    【讨论】:

    • 可能在子查询中使用 r.RedemptionDate 而不是 @Date2 以获得最接近的价格
    • @Blam 好电话,我会进行编辑。我不认为可以在连接的子查询中过滤掉它,它必须移动到其他地方。
    • APPLY 运算符与 JOIN 运算符类似,但区别在于 APPLY 的右侧运算符可以从左侧引用列。
    • 是的,这就是我决定的路线。
    猜你喜欢
    • 2015-04-09
    • 2020-07-03
    • 1970-01-01
    • 1970-01-01
    • 2019-06-22
    • 2020-03-02
    • 2021-02-08
    • 2020-07-09
    • 1970-01-01
    相关资源
    最近更新 更多