我有两张表,一张代表股票交易:
吸墨纸
TradeDate Symbol Shares Price
2014-09-02 ABC 100 157.79
2014-09-10 ABC 200 72.50
2014-09-16 ABC 100 36.82
和存储所有符号的股票拆分历史记录:
拆分
SplitDate Symbol Factor
2014-09-08 ABC 2
2014-09-15 ABC 2
2014-09-20 DEF 2
我正在尝试编写一份反映交易的报告,并包括他们当前的拆分调整因子应该是什么。对于这些表值,我希望报告看起来像:
TradeDate Symbol Shares Price Factor
2014-09-02 ABC 100 157.79 4
2014-09-10 ABC 200 72.50 2
2014-09-16 ABC 100 36.82 1
第一列直接取自 Blotter - 因子应代表自交易发生以来发生的拆分调整( Price 未进行拆分调整)。
使问题复杂化的是每个符号可能有多个分裂,这意味着我不能只OUTER JOIN
Splits 表,否则我将开始复制行。
我有一个子查询,我从https://stackoverflow.com/a/3912258/3063706改编,允许我计算行的乘积,按符号分组,但我怎么只返回所有 Splits 记录的产品在 TradeDate 之后发生 SplitDates ?
类似以下的查询
SELECT tb.TradeDate, tb.Symbol, tb.Shares, tb.Price, ISNULL(s.Factor, 1) AS Factor
FROM Blotter tb
LEFT OUTER JOIN (
SELECT Symbol, EXP(Factor) AS Factor
FROM
(SELECT Symbol, SUM(LOG(ABS(NULLIF(Factor, 0)))) AS Factor
FROM Splits s
WHERE s.SplitDate > tb.TradeDate -- tb is unknown here
GROUP BY Symbol
) splits) s
ON s.Symbol = tb.Symbol
返回错误“消息4104,级别16,状态1,行1多部分标识符”tb.TradeDate“无法绑定。”
如果没有内部WHERE
子句,我会得到如下结果:
TradeDate Symbol Shares Price Factor
2014-09-02 ABC 100 157.79 4
2014-09-10 ABC 200 72.50 4
2014-09-16 ABC 100 36.82 4
更新 Blotter 中的交易行不保证是唯一的,因此我认为使用GROUP BY
排除一个建议的解决方案。
答案 0 :(得分:1)
不过多改变逻辑的一种方法是将因子计算放入表值函数中:
create function dbo.FactorForDate(
@Symbol char(4), @TradeDate datetime
) returns table as
return (
select
exp(Factor) as Factor
from (
select
sum(log(abs(nullif(Factor, 0)))) as Factor
from
Splits s
where
s.SplitDate > @TradeDate and
s.Symbold = @Symbol
) splits
);
select
tb.TradeDate,
tb.Symbol,
tb.Shares,
tb.Price,
isnull(s.Factor, 1) as Factor
from
Blotter tb
outer apply
dbo.FactorForDate(tb.Symbol, tb.TradeDate) s;
在单个语句中执行此操作将类似于:
select
tb.TradeDate,
tb.Symbol,
tb.Shares,
tb.Price,
isnull(exp(sum(log(abs(nullif(factor, 0))))), 1) as Factor
from
Blotter tb
left outer join
Symbol s
on s.Symbol = tb.Symbol and s.SplitDate > tb.TradeDate
group by
tb.TradeDate,
tb.Symbol,
tb.Shares,
tb.Price;
如果能让它发挥作用,这可能会表现得更好。
对于任何语法错误道歉,目前无法访问SQL。