我有以下内容:
CREATE TABLE #MASTER_POSANDTRANS (ID CHAR(30),
QUANTITY INT,
START_OR_TRADE_DATE DATE)
VALUES
('APPLES ','150000','20150501'), ('PEARS','220000','20150501'),
('APPLES ','-75000','20150506'), ('APPLES ','-65000','20150508'),
('APPLES ','10000','20150516'), ('APPLES ','-20000','20150519'
('PEARS','-110000','20150506'), ('PEARS','-100000','20150519')
我希望能够说"一开始我有150,000个苹果,因此我的整体苹果位置很长"
以下是我目前正在解决的这个小谜题:
SELECT
MPT.ID,
MPT.QUANTITY,
MPT.START_OR_TRADE_DATE,
APPLY_RES.QUANTITY as 'FIRST AVAILABLE QUANTITY',
CASE
WHEN APPLY_RES.QUANTITY > 0
THEN 'LONG'
ELSE 'SHORT'
END as 'L/S Indicator'
FROM
#MASTER_POSANDTRANS as MPT
CROSS APPLY
(SELECT TOP 1
MPT_APPLY.QUANTITY
FROM
#MASTER_POSANDTRANS as MPT_APPLY
WHERE
MPT_APPLY.ID = MPT.ID) APPLY_RES
提供的表是,简化了多个查询的结果,并在大约3秒内吐出大约387行的联合alls。 但是,当我尝试将我的解决方案应用于此387行结果时,我的查询返回正确的结果,但需要21秒而不是3秒。
有任何改进建议吗?
谜题更多:
第一个可用的"交易"决定我是长还是短
另一个更复杂的问题(对于那些喜欢谜题的人)是采取平均加权控制来决定在此期间我是长还是短。例如,想象一下,在19号的最后一次苹果交易之后,我剩下0个苹果,我卖掉了另外100万个苹果。这意味着从5月19日到31日,我只有100万。 (31-19)* -1,000,000< (19-1)*(本月出售/购买的苹果的平均数)因此我在那个月持有苹果可被认为是短期的。如果在任何时候两者平衡,我会采用第1点的值。
答案 0 :(得分:0)
您交叉申请选择缺少订单方式(日期?)。这不是确定性的,也不能保证你确实会获得第一记录。
在您的示例数据上,此查询具有更好的查询计划:
SELECT
MPT.ID,
MPT.QUANTITY,
MPT.START_OR_TRADE_DATE
, APPLY_RES.QUANTITY as 'FIRST AVAILABLE QUANTITY',
CASE
WHEN APPLY_RES.QUANTITY > 0
THEN 'LONG'
ELSE 'SHORT'
END as 'L/S Indicator'
From MASTER_POSANDTRANS AS MPT
Inner Join (
Select ID, QUANTITY, N = ROW_NUMBER() over (Partition by ID order by START_OR_TRADE_DATE)
From MASTER_POSANDTRANS
) as APPLY_RES on APPLY_RES.ID = MPT.ID
Where APPLY_RES.N = 1
--Order By MPT.ID, MPT.START_OR_TRADE_DATE