在内部联接中迭代使用MySQL LAG()
我有两个表,我需要在一个循环中迭代地连接它们,以创建值来填充其中一个表我主要是寻找最干净的方法来进行单周期移位联接,详情如下。下面两个输入表的示例:在内部联接中迭代使用MySQL LAG(),mysql,mysql-8.0,Mysql,Mysql 8.0,我有两个表,我需要在一个循环中迭代地连接它们,以创建值来填充其中一个表我主要是寻找最干净的方法来进行单周期移位联接,详情如下。下面两个输入表的示例: 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
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
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
此时,wgt
和ret
组合在一起,为每个条目提供一个新的wgt
(为了简单起见,省略了计算)。这些新权重被插入到holdings表中,这些记录如下所示:
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
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
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
我们再次组合wgt
和ret
以确定新的wgt
值,并将其插入控股表中
这将持续到所有日期,直到我们到达日期列表的末尾(鉴于上述示例,holdings表中的最后一个条目将为date
2019-07-31)
需要注意的是,此过程用于填充holdings表,除非已经存在日期条目。换句话说,我们将对4/30、5/31和7/31执行此过程,但将保留6/28记录,如holdings表所示
所需的样本输出(对于子集)如下所示:
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
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()(或其他运算符),或者是否有另一种方法更干净
我认为没有更干净的方法(即,非基于循环的方法),因为每组条目都依赖于最后一个。欢迎对该方法的其他想法。考虑以下事项;我仍然在使用8.0之前版本的MySQL(我知道),所以这里没有窗口功能
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);
SELECT a.date
, a.ticker a_ticker
, a.wgt
, b.monthend
, b.ticker b_ticker
, b.ret
FROM
( SELECT h.*
, MIN(monthend) monthend
FROM holdings h
LEFT -- if appropriate
JOIN returns r
ON r.monthend > h.date
AND r.ticker = h.ticker
GROUP
BY h.date
, h.ticker
) a
LEFT -- if appropriate
JOIN returns b
ON b.monthend = a.monthen
d AND b.ticker = a.ticker;
+------------+--------+------+------------+------------+--------+------------+
| date | ticker | wgt | monthend | monthEnd | ticker | ret |
+------------+--------+------+------------+------------+--------+------------+
| 2019-03-29 | MTUM | 0.20 | 2019-04-30 | 2019-04-30 | MTUM | 0.02255305 |
| 2019-03-29 | QUAL | 0.20 | 2019-04-30 | 2019-04-30 | QUAL | 0.03794464 |
| 2019-03-29 | SIZE | 0.20 | 2019-04-30 | 2019-04-30 | SIZE | 0.03818616 |
| 2019-03-29 | USMV | 0.20 | 2019-04-30 | 2019-04-30 | USMV | 0.02176873 |
| 2019-03-29 | VLUE | 0.20 | 2019-04-30 | 2019-04-30 | VLUE | 0.03418481 |
| 2019-06-28 | MTUM | 0.20 | 2019-07-31 | 2019-07-31 | MTUM | 0.01795953 |
| 2019-06-28 | QUAL | 0.20 | 2019-07-31 | 2019-07-31 | QUAL | 0.01377500 |
| 2019-06-28 | SIZE | 0.20 | 2019-07-31 | 2019-07-31 | SIZE | 0.01208791 |
| 2019-06-28 | USMV | 0.20 | 2019-07-31 | 2019-07-31 | USMV | 0.01668555 |
| 2019-06-28 | VLUE | 0.20 | 2019-07-31 | 2019-07-31 | VLUE | 0.01601182 |
+------------+--------+------+------------+------------+--------+------------+
冲洗并重复。period(句号)只是序列中的下一个日期?@草莓:没错。