kdb - 功能更新,其中来自 table A 的多列匹配来自 table B 的多列
kdb - functional update where multiple columns from table A match multiple columns from table B
我有以下 2 个示例表。我想将下面的 q-sql 语句变成功能更新...
A:([]orderID:`Aa`Bb`Cc`Bb`Bb`Cc`Aa; date:2016.10.26 2004.09.30 2004.03.10 2016.11.08 2004.02.14 2010.06.01 2008.05.01; number:9 4 5 4 2 7 8; name:`Emp1`Emp2`Emp3`Emp2`Emp2`Emp3`Emp1; cost:100.7 99.8 84.2 85.5 73.9 91.6 94.1; ID:0 1 1 0 1 1 1)
B:([]oid:`Aa`Dd`Cc`Ee`Bb`Cc`Aa; dte:2009.10.26 2020.04.04 2020.03.06 2006.09.28 2004.02.14 2019.09.27 2012.04.30; num:9 5 7 8 2 6 1; nme:`Emp1`Emp2`Emp1`Emp2`Emp2`Emp4`Emp1; cst:100.7 69.8 74.2 85.5 73.9 81.6 94.1; ID:5 5 7 5 7 5 5)
update ID:5 from A where {[a;b;c;d;e]a,b,c,d,e}'[orderID;date;number;name;cost] in (exec {[a;b;c;d;e]a,b,c,d,e}'[oid;dte;num;nme;cst] from B where ID=5)
如果我运行对其进行解析,我会收到以下...
!
`A
,,(in;((';{[a;b;c;d;e]a,b,c,d,e});`orderID;`date;`number;`name;`cost);(?;`B;,,(=;`ID;5);();,((';{[a;b;c;d;e]a,b,c,d,e});`oid;`dte;`num;`nme;`cst)))
0b
(,`ID)!,5
如何翻译此处的 k constraint
语句以在功能更新中工作?
我尝试了以下方法,但是当我检查时它没有更新任何结果...
![`A;enlist(in;((';{[a;b;c;d;e]a,b,c,d,e});`orderID;`date;`number;`name;`cost);(?[`B;enlist(=;`ID;5);();enlist enlist((';{[a;b;c;d;e]a,b,c,d,e});`oid;`dte;`num;`nme;`cst)]));0b;(enlist`ID)!enlist 5i]
如果 orderID, date, number, name, cost
与 table B
的 oid, dte, num, nme, cst
的值相匹配,我的目标是更新 table A
的 ID
列。如果没有,那就保持原样。
首选输出如下所示...
q)A
orderID date number name cost ID
---------------------------------------
Aa 2016.10.26 9 Emp1 100.7 5
Bb 2004.09.30 4 Emp2 99.8 1
Cc 2004.03.10 5 Emp3 84.2 1
Bb 2016.11.08 4 Emp2 85.5 0
Bb 2004.02.14 2 Emp2 73.9 1
Cc 2010.06.01 7 Emp3 91.6 1
Aa 2008.05.01 8 Emp1 94.1 1
谢谢。
如果我没理解错的话,只要其他列匹配,您想更新 A
中 ID
列的值以匹配 B
中的值。
这听起来更像是 left join 的工作,而不是更新语句。鉴于您在上面生成的 tables:
q)show A:([]orderID:`Aa`Bb`Cc`Bb`Bb`Cc`Aa; date:2016.10.26 2004.09.30 2004.03.10 2016.11.08 2004.02.14 2010.06.01 2008.05.01; number:9 4 5 4 2 7 8; name:`Emp1`Emp2`Emp3`Emp2`Emp2`Emp3`Emp1; cost:100.7 99.8 84.2 85.5 73.9 91.6 94.1; ID:0 1 1 0 1 1 1)
orderID date number name cost ID
---------------------------------------
Aa 2016.10.26 9 Emp1 100.7 0
Bb 2004.09.30 4 Emp2 99.8 1
Cc 2004.03.10 5 Emp3 84.2 1
Bb 2016.11.08 4 Emp2 85.5 0
Bb 2004.02.14 2 Emp2 73.9 1
Cc 2010.06.01 7 Emp3 91.6 1
Aa 2008.05.01 8 Emp1 94.1 1
q)show B:([]oid:`Aa`Dd`Cc`Ee`Bb`Cc`Aa; dte:2009.10.26 2020.04.04 2020.03.06 2006.09.28 2004.02.14 2019.09.27 2012.04.30; num:9 5 7 8 2 6 1; nme:`Emp1`Emp2`Emp1`Emp2`Emp2`Emp4`Emp1; cst:100.7 69.8 74.2 85.5 73.9 81.6 94.1; ID:5 5 7 5 7 5 5)
oid dte num nme cst ID
--------------------------------
Aa 2009.10.26 9 Emp1 100.7 5
Dd 2020.04.04 5 Emp2 69.8 5
Cc 2020.03.06 7 Emp1 74.2 7
Ee 2006.09.28 8 Emp2 85.5 5
Bb 2004.02.14 2 Emp2 73.9 7
Cc 2019.09.27 6 Emp4 81.6 5
Aa 2012.04.30 1 Emp1 94.1 5
我看到 A
中的第五行与 B
中的一行匹配,因此 A
中的第五行应更新为 B
中的相应值: 7. 您可以像这样使用左连接来实现此目的:
q)A lj 5!cols[A] xcol B
orderID date number name cost ID
---------------------------------------
Aa 2016.10.26 9 Emp1 100.7 0
Bb 2004.09.30 4 Emp2 99.8 1
Cc 2004.03.10 5 Emp3 84.2 1
Bb 2016.11.08 4 Emp2 85.5 0
Bb 2004.02.14 2 Emp2 73.9 7
Cc 2010.06.01 7 Emp3 91.6 1
Aa 2008.05.01 8 Emp1 94.1 1
简单解释一下上面的内容:xcol function forces the schema of B
to match A
, and the (!)enkey 运算符将前五列设置为键。最后,左连接执行您想要的更新。
如果您想一次只专注于更新一个 ID
值,您可以在左加入之前使用函数 select 过滤 B:
A lj 5!cols[A] xcol ?[B;enlist(=;`ID;5);0b;()]
如果我有任何误解,请告诉我。您的输出 table 与我理解的您的目标不太相符。第一列是否应该在 A
和 B
中匹配?
q)A:([]orderID:`Aa`Bb`Cc`Bb`Bb`Cc`Aa; date:2009.10.26 2004.09.30 2004.03.10 2016.11.08 2004.02.14 2010.06.01 2008.05.01; number:9 4 5 4 2 7 8; name:`Emp1`Emp2`Emp3`Emp2`Emp2`Emp3`Emp1; cost:100.7 99.8 84.2 85.5 73.9 91.6 94.1; ID:0 1 1 0 1 1 1)
q)A lj 5!cols[A] xcol select from B where ID=5
orderID date number name cost ID
---------------------------------------
Aa 2009.10.26 9 Emp1 100.7 5
Bb 2004.09.30 4 Emp2 99.8 1
Cc 2004.03.10 5 Emp3 84.2 1
Bb 2016.11.08 4 Emp2 85.5 0
Bb 2004.02.14 2 Emp2 73.9 1
Cc 2010.06.01 7 Emp3 91.6 1
Aa 2008.05.01 8 Emp1 94.1 1
我有以下 2 个示例表。我想将下面的 q-sql 语句变成功能更新...
A:([]orderID:`Aa`Bb`Cc`Bb`Bb`Cc`Aa; date:2016.10.26 2004.09.30 2004.03.10 2016.11.08 2004.02.14 2010.06.01 2008.05.01; number:9 4 5 4 2 7 8; name:`Emp1`Emp2`Emp3`Emp2`Emp2`Emp3`Emp1; cost:100.7 99.8 84.2 85.5 73.9 91.6 94.1; ID:0 1 1 0 1 1 1)
B:([]oid:`Aa`Dd`Cc`Ee`Bb`Cc`Aa; dte:2009.10.26 2020.04.04 2020.03.06 2006.09.28 2004.02.14 2019.09.27 2012.04.30; num:9 5 7 8 2 6 1; nme:`Emp1`Emp2`Emp1`Emp2`Emp2`Emp4`Emp1; cst:100.7 69.8 74.2 85.5 73.9 81.6 94.1; ID:5 5 7 5 7 5 5)
update ID:5 from A where {[a;b;c;d;e]a,b,c,d,e}'[orderID;date;number;name;cost] in (exec {[a;b;c;d;e]a,b,c,d,e}'[oid;dte;num;nme;cst] from B where ID=5)
如果我运行对其进行解析,我会收到以下...
!
`A
,,(in;((';{[a;b;c;d;e]a,b,c,d,e});`orderID;`date;`number;`name;`cost);(?;`B;,,(=;`ID;5);();,((';{[a;b;c;d;e]a,b,c,d,e});`oid;`dte;`num;`nme;`cst)))
0b
(,`ID)!,5
如何翻译此处的 k constraint
语句以在功能更新中工作?
我尝试了以下方法,但是当我检查时它没有更新任何结果...
![`A;enlist(in;((';{[a;b;c;d;e]a,b,c,d,e});`orderID;`date;`number;`name;`cost);(?[`B;enlist(=;`ID;5);();enlist enlist((';{[a;b;c;d;e]a,b,c,d,e});`oid;`dte;`num;`nme;`cst)]));0b;(enlist`ID)!enlist 5i]
如果 orderID, date, number, name, cost
与 table B
的 oid, dte, num, nme, cst
的值相匹配,我的目标是更新 table A
的 ID
列。如果没有,那就保持原样。
首选输出如下所示...
q)A
orderID date number name cost ID
---------------------------------------
Aa 2016.10.26 9 Emp1 100.7 5
Bb 2004.09.30 4 Emp2 99.8 1
Cc 2004.03.10 5 Emp3 84.2 1
Bb 2016.11.08 4 Emp2 85.5 0
Bb 2004.02.14 2 Emp2 73.9 1
Cc 2010.06.01 7 Emp3 91.6 1
Aa 2008.05.01 8 Emp1 94.1 1
谢谢。
如果我没理解错的话,只要其他列匹配,您想更新 A
中 ID
列的值以匹配 B
中的值。
这听起来更像是 left join 的工作,而不是更新语句。鉴于您在上面生成的 tables:
q)show A:([]orderID:`Aa`Bb`Cc`Bb`Bb`Cc`Aa; date:2016.10.26 2004.09.30 2004.03.10 2016.11.08 2004.02.14 2010.06.01 2008.05.01; number:9 4 5 4 2 7 8; name:`Emp1`Emp2`Emp3`Emp2`Emp2`Emp3`Emp1; cost:100.7 99.8 84.2 85.5 73.9 91.6 94.1; ID:0 1 1 0 1 1 1)
orderID date number name cost ID
---------------------------------------
Aa 2016.10.26 9 Emp1 100.7 0
Bb 2004.09.30 4 Emp2 99.8 1
Cc 2004.03.10 5 Emp3 84.2 1
Bb 2016.11.08 4 Emp2 85.5 0
Bb 2004.02.14 2 Emp2 73.9 1
Cc 2010.06.01 7 Emp3 91.6 1
Aa 2008.05.01 8 Emp1 94.1 1
q)show B:([]oid:`Aa`Dd`Cc`Ee`Bb`Cc`Aa; dte:2009.10.26 2020.04.04 2020.03.06 2006.09.28 2004.02.14 2019.09.27 2012.04.30; num:9 5 7 8 2 6 1; nme:`Emp1`Emp2`Emp1`Emp2`Emp2`Emp4`Emp1; cst:100.7 69.8 74.2 85.5 73.9 81.6 94.1; ID:5 5 7 5 7 5 5)
oid dte num nme cst ID
--------------------------------
Aa 2009.10.26 9 Emp1 100.7 5
Dd 2020.04.04 5 Emp2 69.8 5
Cc 2020.03.06 7 Emp1 74.2 7
Ee 2006.09.28 8 Emp2 85.5 5
Bb 2004.02.14 2 Emp2 73.9 7
Cc 2019.09.27 6 Emp4 81.6 5
Aa 2012.04.30 1 Emp1 94.1 5
我看到 A
中的第五行与 B
中的一行匹配,因此 A
中的第五行应更新为 B
中的相应值: 7. 您可以像这样使用左连接来实现此目的:
q)A lj 5!cols[A] xcol B
orderID date number name cost ID
---------------------------------------
Aa 2016.10.26 9 Emp1 100.7 0
Bb 2004.09.30 4 Emp2 99.8 1
Cc 2004.03.10 5 Emp3 84.2 1
Bb 2016.11.08 4 Emp2 85.5 0
Bb 2004.02.14 2 Emp2 73.9 7
Cc 2010.06.01 7 Emp3 91.6 1
Aa 2008.05.01 8 Emp1 94.1 1
简单解释一下上面的内容:xcol function forces the schema of B
to match A
, and the (!)enkey 运算符将前五列设置为键。最后,左连接执行您想要的更新。
如果您想一次只专注于更新一个 ID
值,您可以在左加入之前使用函数 select 过滤 B:
A lj 5!cols[A] xcol ?[B;enlist(=;`ID;5);0b;()]
如果我有任何误解,请告诉我。您的输出 table 与我理解的您的目标不太相符。第一列是否应该在 A
和 B
中匹配?
q)A:([]orderID:`Aa`Bb`Cc`Bb`Bb`Cc`Aa; date:2009.10.26 2004.09.30 2004.03.10 2016.11.08 2004.02.14 2010.06.01 2008.05.01; number:9 4 5 4 2 7 8; name:`Emp1`Emp2`Emp3`Emp2`Emp2`Emp3`Emp1; cost:100.7 99.8 84.2 85.5 73.9 91.6 94.1; ID:0 1 1 0 1 1 1)
q)A lj 5!cols[A] xcol select from B where ID=5
orderID date number name cost ID
---------------------------------------
Aa 2009.10.26 9 Emp1 100.7 5
Bb 2004.09.30 4 Emp2 99.8 1
Cc 2004.03.10 5 Emp3 84.2 1
Bb 2016.11.08 4 Emp2 85.5 0
Bb 2004.02.14 2 Emp2 73.9 1
Cc 2010.06.01 7 Emp3 91.6 1
Aa 2008.05.01 8 Emp1 94.1 1