kdb - 如何递归更新 table 中的行?

kdb - How can I recursively update rows in a table?

我有 table 报价数据

q)t:([]symbol:8#`ABC;receiverIMID:`rep1`rep1`rep2`rep2`rep1`rep1`rep2`rep2;ID:`2019`2018`2019`2018`2019`2018`2019`2018;priorID:`````2018`2017`2018`2017;date:8#.z.Z;priorDate:(0Nz;0Nz;0Nz;0Nz;.z.Z;.z.Z-1;.z.Z;.z.Z-1);status:8#1)
q)t
symbol receiverIMID ID   priorID date                    priorDate               status
---------------------------------------------------------------------------------------
ABC    rep1         2019         2020.06.30T18:33:18.039                         1
ABC    rep1         2018         2020.06.30T18:33:18.039                         1
ABC    rep2         2019         2020.06.30T18:33:18.039                         1
ABC    rep2         2018         2020.06.30T18:33:18.039                         1
ABC    rep1         2019 2018    2020.06.30T18:33:18.039 2020.06.30T18:33:18.039 1
ABC    rep1         2018 2017    2020.06.30T18:33:18.039 2020.06.29T18:33:18.039 1
ABC    rep2         2019 2018    2020.06.30T18:33:18.039 2020.06.30T18:33:18.039 1
ABC    rep2         2018 2017    2020.06.30T18:33:18.039 2020.06.29T18:33:18.039 1

和一个table的历史数据

q)t2:([]SYM:2#`ABC;IMID:`rep1`rep2;ID:2#`2017;DATE:2#.z.Z-1;PS:15)
q)t2
SYM IMID ID   DATE                    PS
----------------------------------------
ABC rep1 2017 2020.06.29T18:36:48.905 15
ABC rep2 2017 2020.06.29T18:36:48.905 15

如果 SYM, IMID, ID 匹配 symbol, recieverIMID, ID (or) priorID 来自 table t...

tt:select OID:{$[null x;y;x]}'[priorID;ID],symbol, receiverIMID, status from t
th:select ID,SYM,IMID,PS from t2
update status:(exec status from (tt lj 3!cols[tt] xcol th)) from `t

对 table t

进行了以下更新
symbol receiverIMID ID   priorID date                    priorDate               status
--------------------------------------------------------------------------------------
ABC    rep1         2019         2020.06.30T00:00:00.000                         1
ABC    rep1         2018         2020.06.30T00:00:00.000                         1
ABC    rep2         2019         2020.06.30T00:00:00.000                         1
ABC    rep2         2018         2020.06.30T00:00:00.000                         1
ABC    rep1         2019 2018    2020.06.30T00:00:00.000 2020.06.30T00:00:00.000 1
ABC    rep1         2018 2017    2020.06.30T00:00:00.000 2020.06.29T00:00:00.000 15
ABC    rep2         2019 2018    2020.06.30T00:00:00.000 2020.06.30T00:00:00.000 1
ABC    rep2         2018 2017    2020.06.30T00:00:00.000 2020.06.29T00:00:00.000 15

然后我想执行刚刚更新的行的 ID,用 ID 更新 table t 的所有行,然后检查如果 IDpriorID 中,例如,在 2017 年更新 priorID 之后,然后在 2018 年更新 ID 的其他行,并检查 2018 年是否在 [=27] =].它看起来像下面...

symbol receiverIMID ID   priorID date                    priorDate               status
--------------------------------------------------------------------------------------
ABC    rep1         2019         2020.06.30T00:00:00.000                         1
ABC    rep1         2018         2020.06.30T00:00:00.000                         15
ABC    rep2         2019         2020.06.30T00:00:00.000                         1
ABC    rep2         2018         2020.06.30T00:00:00.000                         15
ABC    rep1         2019 2018    2020.06.30T00:00:00.000 2020.06.30T00:00:00.000 1
ABC    rep1         2018 2017    2020.06.30T00:00:00.000 2020.06.29T00:00:00.000 15
ABC    rep2         2019 2018    2020.06.30T00:00:00.000 2020.06.30T00:00:00.000 1
ABC    rep2         2018 2017    2020.06.30T00:00:00.000 2020.06.29T00:00:00.000 15

我将重复此过程,更新存在 ID 的所有行并检查 ID 是否在 priorID 中。在这种情况下,2019 不在 priorID 中,因此我们将退出该函数。最终更新 table 如下所示...

symbol receiverIMID ID   priorID date                    priorDate               status
--------------------------------------------------------------------------------------
ABC    rep1         2019         2020.06.30T00:00:00.000                         15
ABC    rep1         2018         2020.06.30T00:00:00.000                         15
ABC    rep2         2019         2020.06.30T00:00:00.000                         15
ABC    rep2         2018         2020.06.30T00:00:00.000                         15
ABC    rep1         2019 2018    2020.06.30T00:00:00.000 2020.06.30T00:00:00.000 15
ABC    rep1         2018 2017    2020.06.30T00:00:00.000 2020.06.29T00:00:00.000 15
ABC    rep2         2019 2018    2020.06.30T00:00:00.000 2020.06.30T00:00:00.000 15
ABC    rep2         2018 2017    2020.06.30T00:00:00.000 2020.06.29T00:00:00.000 15

我假设我们希望使用 over (/) 进行递归,但我不确定如何正确实施递归查找和更新。预先感谢您的帮助。

我可能是 mis-interpreting 但这看起来像一个 parent-child ID 设置,我将处理它作为具有 parents 到 children 的映射然后跟随一直映射到它的最低 child - 然后加入 child 信息。 (我认为你在做同样的事情,但反过来?)。很难从你的样本中准确知道。无论哪种方式,这可能会给您一个想法:

q)t:([]symbol:8#`ABC;receiverIMID:`rep1`rep1`rep2`rep2`rep1`rep1`rep2`rep2;ID:`2019`2018`2019`2018`2019`2018`2019`2018;priorID:`````2018`2017`2018`2017;date:8#.z.Z;priorDate:(0Nz;0Nz;0Nz;0Nz;.z.Z;.z.Z-1;.z.Z;.z.Z-1);status:8#1);
q)t2:([]SYM:2#`ABC;IMID:`rep1`rep2;ID:2#`2017;DATE:2#.z.Z-1;PS:15);
q)childMap:exec ID!priorID from t where not null priorID; /might want to make this unique
q)(update child:.Q.fu[{x^childMap x}/;ID] from t) lj 3!select symbol:SYM,receiverIMID:IMID,child:ID,status:PS from t2
symbol receiverIMID ID   priorID date                    priorDate               status child
---------------------------------------------------------------------------------------------
ABC    rep1         2019         2020.07.01T03:54:44.235                         15     2017
ABC    rep1         2018         2020.07.01T03:54:44.235                         15     2017
ABC    rep2         2019         2020.07.01T03:54:44.235                         15     2017
ABC    rep2         2018         2020.07.01T03:54:44.235                         15     2017
ABC    rep1         2019 2018    2020.07.01T03:54:44.235 2020.07.01T03:54:44.235 15     2017
ABC    rep1         2018 2017    2020.07.01T03:54:44.235 2020.06.30T03:54:44.235 15     2017
ABC    rep2         2019 2018    2020.07.01T03:54:44.235 2020.07.01T03:54:44.235 15     2017
ABC    rep2         2018 2017    2020.07.01T03:54:44.235 2020.06.30T03:54:44.235 15     2017

以下函数将根据需要递归编辑 table 的行:

func:{
 tt:select OID:{$[null x;y;x]}'[priorID;ID],symbol, receiverIMID, status from t; 
 $[x[0]=0; 
  th:select ID,SYM,IMID,PS from t2; 
  th: select ID,symbol,receiverIMID,status from t where ID in x[2]
  ]; 
 changedrowpriorids: exec OID from (tt ij 3!cols[tt] xcol th); 
 changedrowids: exec ID from t where priorID in changedrowpriorids; 
 update status:(exec status from (tt lj 3!cols[tt] xcol th)) from `t; 
 update status: first (exec distinct status from t where priorID in changedrowpriorids) from `t where ID in changedrowids; 
 (1; not (`$()) ~ exec ID from t where priorID in changedrowids;changedrowids) 
 }

所以:

q)t:([]symbol:8#`ABC;receiverIMID:`rep1`rep1`rep2`rep2`rep1`rep1`rep2`rep2;ID:`2019`2018`2019`2018`2019`2018`2019`2018;priorID:`````2018`2017`2018`2017;date:8#.z.Z;priorDate:(0Nz;0Nz;0Nz;0Nz;.z.Z;.z.Z-1;.z.Z;.z.Z-1);status:8#1)
q)t2:([]SYM:2#`ABC;IMID:`rep1`rep2;ID:2#`2017;DATE:2#.z.Z-1;PS:15)
q)\c 200 200
q)t
symbol receiverIMID ID   priorID date                    priorDate               status
---------------------------------------------------------------------------------------
ABC    rep1         2019         2020.07.01T11:49:39.108                         1
ABC    rep1         2018         2020.07.01T11:49:39.108                         1
ABC    rep2         2019         2020.07.01T11:49:39.108                         1
ABC    rep2         2018         2020.07.01T11:49:39.108                         1
ABC    rep1         2019 2018    2020.07.01T11:49:39.108 2020.07.01T11:49:39.108 1
ABC    rep1         2018 2017    2020.07.01T11:49:39.108 2020.06.30T11:49:39.108 1
ABC    rep2         2019 2018    2020.07.01T11:49:39.108 2020.07.01T11:49:39.108 1
ABC    rep2         2018 2017    2020.07.01T11:49:39.108 2020.06.30T11:49:39.108 1
q)func\[{x[1]=1b};(0;1b;`)]
0 1b `
1 1b `2018`2018
1 0b `2019`2019
q)t
symbol receiverIMID ID   priorID date                    priorDate               status
---------------------------------------------------------------------------------------
ABC    rep1         2019         2020.07.01T11:49:39.108                         15
ABC    rep1         2018         2020.07.01T11:49:39.108                         15
ABC    rep2         2019         2020.07.01T11:49:39.108                         15
ABC    rep2         2018         2020.07.01T11:49:39.108                         15
ABC    rep1         2019 2018    2020.07.01T11:49:39.108 2020.07.01T11:49:39.108 15
ABC    rep1         2018 2017    2020.07.01T11:49:39.108 2020.06.30T11:49:39.108 15
ABC    rep2         2019 2018    2020.07.01T11:49:39.108 2020.07.01T11:49:39.108 15
ABC    rep2         2018 2017    2020.07.01T11:49:39.108 2020.06.30T11:49:39.108 15