kdb - функциональное обновление, когда несколько столбцов из таблицы A соответствуют нескольким столбцам из таблицы B - PullRequest
1 голос
/ 03 апреля 2020

У меня есть следующие 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]

Моя цель - обновить столбец ID table A, если orderID, date, number, name, cost соответствует значениям oid, dte, num, nme, cst из table B. Если нет, то оставьте как есть.

Предпочтительный вывод будет выглядеть следующим образом ...

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

Спасибо.

Ответы [ 2 ]

3 голосов
/ 04 апреля 2020
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
3 голосов
/ 04 апреля 2020

Если я правильно понимаю, вы хотели бы обновить значение столбца ID в A, чтобы оно соответствовало значению в B всякий раз, когда совпадают другие столбцы.

Это звучит больше как задание для левого соединения , чем оператор обновления. Учитывая таблицы, которые вы генерируете выше:

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 заставляет схему B соответствует A, а оператор (!) enkey устанавливает первые пять столбцов в качестве ключей. Наконец, левое соединение выполняет обновление, которое вы хотите.

Если вы хотите сосредоточиться на обновлении только одного значения ID за раз, вы можете выполнить фильтрацию по B с помощью функционального выбора перед присоединением слева:

A lj 5!cols[A] xcol ?[B;enlist(=;`ID;5);0b;()]

Дайте мне знать, если я что-то не так понял. Ваша таблица результатов не совсем соответствует тому, что я понял как ваша цель. Должен ли этот первый столбец совпадать как в A, так и в B?

...