构建查询,从多个表

时间:2015-06-22 17:23:06

标签: sql sql-server join

我需要构建一个查询,其中包含投资组合中每个基金的公平市场价值。这些不是公共实体,因此公平市场价值报表不是每个月都会出现的。当我逐步执行基于游标的操作时,计算很简单,但我想构建一个一次性返回所有结果的查询。以下是其工作原理的简化版本:

tblFMV包含FMVDate,FundID,FairMarketValue

tblTransaction包含TransactionDate,FundID,交易金额(可能是正数还是负数)

要计算给定日期的FMV,我在tblFMV的给定日期或之前获得最新的FMV,然后我在FMV日期之前或之后添加来自tblTransaction的任何交易,直至并包括给定日期。< BR />

例:
tblFMV

Date, FundID, FMV
1/1/2015, 1, $1000
4/1/2015, 1, $1500

tblTransaction

TransactionDate, FundID, TransactionAmount
1/3/2015,        1,      $100
2/5/2015,        1,      -$75

要获得2015年1月1日的FMV,我将从2005年1月1日的$ 1000条目开始,并从2015年1月3日起为100美元的FMV增加100美元 2015年3月1日的FMV为1025美元 2015年4月1日的FMV是1500美元(此时我可以计算增益,但这是另一回事)

我有另一个简单的表格,其中包含一年中每个月的月份开始日期:

1/1/2015
2/1/2015 
3/1/2015 
etc

我想加入所有三个表来得到一个如下所示的结果集:

FMVDate, FundID, FMV
1/1/2015, 1, $1000
2/1/2015, 1, $1100
3/1/2015, 1, $1025
4/1/2015, 1, $1500
...

就像我说的那样,我目前正在代码中执行几个步骤。我得到了最新的FMV,总结和交易,并将它们添加到总数中。您对如何创建查询(或多个查询)以返回结果集有任何想法吗?这是在SQL服务器中。

由于

2 个答案:

答案 0 :(得分:1)

你可以试试这个:

SELECT MON, FUNDID, 
   LAST_FMV + CASE WHEN CHANGES IS NOT NULL THEN CHANGES ELSE 0 END FMV 
FROM (
    SELECT MON, FUNDID, LAST_DATE, LAST_FMV , 
            (SELECT SUM(TRANSACTIONAMOUNT) FROM TBLTRANSACTION T 
             WHERE T.FUNDID = N.FUNDID 
                  AND T.TRANSACTIONDATE > N.LAST_DATE 
                  AND T.TRANSACTIONDATE < N.MON
            ) AS CHANGES
    FROM (
        SELECT MON,M.FUNDID, LAST_DATE, M.FMV AS LAST_FMV 
        FROM 
           (SELECT MON , MAX(L.DATE) LAST_DATE, L.FUNDID
                FROM MONTHS M
                LEFT JOIN TBLFMV L
                ON M.MON > = L.DATE
                GROUP BY MON, FUNDID) FMV
        JOIN TBLFMV M
        ON FMV.LAST_DATE = M.DATE AND FMV.FUNDID = M.FUNDID
    ) N
) C

答案 1 :(得分:0)

这很快,很粗糙,而且非常未经测试,但看看这是否接近。至少,想法是将每个基金的每月交易总和为“&#34;增量&#34;到FMV,然后将增量添加到起始FMV,并导出结果。 &#34;当前月份&#34; FMV将等于 last - 月份开始FMV加上之前月份的增量:

select dateadd(month,1,a.month_begin_date) month_begin_date,b.fund_id,b.fmv+c.fmv_delta FMV
  from months a
  cross apply tblfmv
  join (select month(transaction_date) tmonth,year(transaction_date) tyear ,fundid,sum(transaction) fmv_delta
          from tbltransaction
         group by month(transaction_date),year(transaction_date),fundid) c
  on c.tmonth=month(a.month_begin_Date)
  and c.tyear=year(a.month_begin_Date)
  and tblfmv.fundid=c.fundid