【发布时间】:2020-10-27 07:13:29
【问题描述】:
我有两个表,我需要在一个循环中迭代地加入它们以创建值来填充其中一个表。 我主要是在寻找最简洁的方法来进行单周期移位连接,详情如下。以下两个输入表的示例:
DROP TABLE IF EXISTS holdings;
CREATE TABLE holdings
(date DATE NOT NULL
,ticker CHAR(4) NOT NULL
,wgt DECIMAL(5,2)
,PRIMARY KEY(date,ticker)
);
INSERT INTO holdings VALUES
('2019-03-29','MTUM',0.2),
('2019-03-29','QUAL',0.2),
('2019-03-29','SIZE',0.2),
('2019-03-29','USMV',0.2),
('2019-03-29','VLUE',0.2),
('2019-06-28','MTUM',0.2),
('2019-06-28','QUAL',0.2),
('2019-06-28','SIZE',0.2),
('2019-06-28','USMV',0.2),
('2019-06-28','VLUE',0.2);
DROP TABLE IF EXISTS returns;
CREATE TABLE returns
(monthEnd DATE NOT NULL
,ticker CHAR(4) NOT NULL
,ret DECIMAL(11,8) NOT NULL
,PRIMARY KEY(monthend,ticker)
);
INSERT INTO returns VALUES
('2019-03-29', 'USMV' , 0.02715291),
('2019-03-29', 'SIZE' , 0.00512113),
('2019-03-29', 'VLUE' , -0.00943159),
('2019-03-29', 'MTUM' , 0.02118479),
('2019-03-29', 'QUAL' , 0.02533432),
('2019-04-30', 'USMV' , 0.02176873),
('2019-04-30', 'SIZE' , 0.03818616),
('2019-04-30', 'VLUE' , 0.03418481),
('2019-04-30', 'MTUM' , 0.02255305),
('2019-04-30', 'QUAL' , 0.03794464),
('2019-05-31', 'VLUE' , -0.09601646),
('2019-05-31', 'MTUM' , -0.02196844),
('2019-05-31', 'QUAL' , -0.06582526),
('2019-05-31', 'USMV' , -0.01614514),
('2019-05-31', 'SIZE' , -0.06918445),
('2019-06-28', 'QUAL' , 0.07073081),
('2019-06-28', 'VLUE' , 0.09571038),
('2019-06-28', 'MTUM' , 0.06121113),
('2019-06-28', 'USMV' , 0.04984654),
('2019-06-28', 'SIZE' , 0.07531133),
('2019-07-31', 'QUAL' , 0.013775 ),
('2019-07-31', 'MTUM' , 0.01795953),
('2019-07-31', 'SIZE' , 0.01208791),
('2019-07-31', 'VLUE' , 0.01601182),
('2019-07-31', 'USMV' , 0.01668555);
这里的第一步是将 holdings 加入 returns,将日期对齐移动一个句点,这样第一次迭代的输出如下:
date portName ticker wgt monthEnd ticker ret
2019-03-29 test MTUM 0.2 2019-04-30 MTUM 0.02255305
2019-03-29 test QUAL 0.2 2019-04-30 QUAL 0.03794464
2019-03-29 test SIZE 0.2 2019-04-30 SIZE 0.03818616
2019-03-29 test USMV 0.2 2019-04-30 USMV 0.02176873
2019-03-29 test VLUE 0.2 2019-04-30 VLUE 0.03418481
此时,wgt 和 ret 组合在一起,为每个条目提供一个新的 wgt(为简单起见,省略了计算)。这些新的权重被插入到 holdings 表中,这些记录如下所示:
date portName ticker wgt
2019-04-30 test MTUM 0.201442484998052
2019-04-30 test QUAL 0.202261035805858
2019-04-30 test SIZE 0.198273711216605
2019-04-30 test USMV 0.202619777232855
2019-04-30 test VLUE 0.19540299074663
下一步是应用与之前相同的程序,获取这些权重,并结合一个周期移位的回报,以产生如下所示的输出:
date portName ticker wgt monthEnd ticker ret
2019-04-30 test MTUM 0.201442484998052 2019-05-31 MTUM -0.02196844
2019-04-30 test QUAL 0.202261035805858 2019-05-31 QUAL -0.06582526
2019-04-30 test SIZE 0.198273711216605 2019-05-31 SIZE -0.06918445
2019-04-30 test USMV 0.202619777232855 2019-05-31 USMV -0.01614514
2019-04-30 test VLUE 0.19540299074663 2019-05-31 VLUE -0.09601646
我们再次组合wgt 和ret 以确定新的wgt 值并将它们插入到holdings 表中。
这将持续到所有日期,直到我们到达日期列表的末尾(鉴于上述示例,holdings 表中的最后一个条目将具有 date2019-07-31)。
需要注意的是,当日期条目已存在时,此过程用于填充 holdings 表except。换句话说,我们会为 4/30、5/31 和 7/31 执行此过程,但会将 6/28 记录保留在 holdings 表中。
所需的样本输出(对于子集)如下所示:
date portName ticker wgt
2019-03-29 test MTUM 0.2
2019-03-29 test QUAL 0.2
2019-03-29 test SIZE 0.2
2019-03-29 test USMV 0.2
2019-03-29 test VLUE 0.2
2019-04-30 test MTUM 0.201442484998052
2019-04-30 test QUAL 0.202261035805858
2019-04-30 test SIZE 0.198273711216605
2019-04-30 test USMV 0.202619777232855
2019-04-30 test VLUE 0.19540299074663
2019-05-31 test MTUM 0.205430582
2019-05-31 test QUAL 0.201024226
2019-05-31 test SIZE 0.198113682
2019-05-31 test USMV 0.204236958
2019-05-31 test VLUE 0.205066864
2019-06-28 test MTUM 0.2
2019-06-28 test QUAL 0.2
2019-06-28 test SIZE 0.2
2019-06-28 test USMV 0.2
2019-06-28 test VLUE 0.2
我的基本方法是在唯一的日期列表上使用循环,首先检查“currentDate”值是否已经在 holdings 表中,然后在按照所述进行计算之前加入. 专门寻找有关执行上述单周期移位联接的最简洁方法的输入。 我来自 SQL Server,我通常会在其中创建一个可以使用的虚拟“rowNum”列(即,a.rowNum = b.rowNum+1)进行移位。想知道是否有办法在连接中使用 LAG() (或其他运算符),是否有另一种更简洁的方法。
我认为没有更简洁(即非基于循环)的方法,因为每组条目都依赖于最后一个。欢迎对方法提出其他想法。
【问题讨论】:
-
“句号”只是序列中的下一个日期?
-
@Strawberry 没错。