我有3个表,1(PortfolioInstrument)持有在portoflio中持有的工具(工具),持有(持有)跨越日期范围(DateAdded,DateRemoved)。 另一个(价格)持有每种工具(工具)的每日(TradeDate)收盘价([关闭])。 第三个可能有用,(CalcDate)保存我们重新计算持股的日期(CalcDate),并从投资组合中添加和删除工具。
SELECT SUM([Close]*Holding), TradeDate
FROM Price p1 INNER JOIN PortfolioInstrument pio ON pio.Instrument = p1.Instrument
AND pio.Portfolio = 3
WHERE EXISTS (SELECT TradeDate FROM Price p
INNER JOIN PortfolioInstrument pi ON pi.Instrument = p.Instrument AND Portfolio = 3
WHERE TradeDate >= pi.DateAdded AND
(TradeDate < pi.DateRemoved OR pi.DateRemoved IS NULL)
AND p1.ID = p.ID GROUP BY TradeDate) GROUP BY TradeDate
以下是PortfolioInstrument数据集的示例
ID Portfolio Instrument Holding DateAdded DateRemoved
16256 3 410 714.28571 2007-10-01 00:00:00.0 2007-11-01 00:00:00.0
16257 3 611 564.97174 2007-10-01 00:00:00.0 2007-11-01 00:00:00.0
16258 3 538 1,797.75281 2007-10-01 00:00:00.0 2007-11-01 00:00:00.0
...
16302 3 5352 1,067,319.75 2008-02-01 00:00:00.0 2008-04-01 00:00:00.0
16303 3 5353 1,057,800.875 2008-02-01 00:00:00.0 2008-04-01 00:00:00.0
16304 3 11952 0 2008-02-29 00:00:00.0 2008-04-01 00:00:00.0
16305 3 11952 261,484,400 2008-04-01 00:00:00.0 2008-05-01 00:00:00.0
...
16315 3 8374 14,199.99902 2009-01-30 00:00:00.0 <null>
16316 3 11952 246,102,960 2009-01-30 00:00:00.0 2009-02-27 00:00:00.0
16317 3 11952 246,148,912 2009-02-27 00:00:00.0 2009-04-01 00:00:00.0
这个问题在于它包含所有拥有DateRemoved&lt; TradeDate所以每个重新计算日期都有一个跳转,它们应该从集合中删除。看看Stackoverflow上的各种DateDiff方法,但在这种情况下无法解决如何使用它们进行分组的问题。另请注意,现金工具(工具= 11952)在某个时刻进入投资组合,然后每个月获得一个条目,因为您可以看到它在几个月内减少到0,这在我生产的SQL中我认为无关紧要
THX。
大卫
答案 0 :(得分:1)
为什么要使用相同连接的另一个实例并不是很清楚。如果要排除DateRemoved <= TradeDate
中的特定馆藏,您可以直接在WHERE子句中检查:
SELECT SUM(p1.[Close]*pio.Holding), TradeDate
FROM Price p1
INNER JOIN PortfolioInstrument pio
ON pio.Instrument = p1.Instrument AND pio.Portfolio = 3
WHERE p1.TradeDate >= pio.DateAdded
AND (p1.TradeDate < pio.DateRemoved OR pio.DateRemoved IS NULL)
GROUP BY p1.TradeDate
;
但是,如果要丢弃相同TradeDate
行的整个组,其中至少有一行满足条件DateRemoved <= TradeDate
,则可以使用HAVING子句,像这样:
SELECT SUM(p1.[Close]*pio.Holding), TradeDate
FROM Price p1
INNER JOIN PortfolioInstrument pio
ON pio.Instrument = p1.Instrument AND pio.Portfolio = 3
GROUP BY p1.TradeDate
HAVING COUNT(CASE WHEN p1.TradeDate <= pio.DateRemoved) THEN 1 END) = 0
;
与适用于各行的WHERE子句不同,HAVING是针对一组行进行评估的。在这种情况下,COUNT()函数用于计算组中有多少行p1.TradeDate <= pio.DateRemoved
。如果至少有一个,那么该组将从输出中被丢弃,因为我在这里假设的要求是没有这样的行。
答案 1 :(得分:0)
无法找到前进的方法,最终拉入原始行并在代码中进行计算。