#kdb
#kdb
Вопрос:
У меня есть таблица с 2 столбцами с ключами. Это выглядит так
date sym type val
2020.01.02 ABC 100
2020.01.02 ABC a2 200
2020.01.02 ANX 300
2020.01.02 XYZ a3 400
2020.01.02 XYZ a2 100
Обратите внимание, что type
столбец имеет некоторые нулевые значения. Я хочу транспонировать эту таблицу в
date sym type_null type_a2 type_a3
2020.01.02 ABC 100 200 0
2020.01.02 ANX 300 0 0
2020.01.02 XYZ 0 100 400
Обратите внимание, что если type
значение равно null, мы присваиваем ему значение 0. Я могу сделать это
update type_a2:?[type_a2=0n;0;type_a2]
после того, как таблица была транспонирована. Есть ли более элегантный способ сделать это?
Что касается транспонирования, я понятия не имею, как это сделать. Я попробовал следующее, но это не сработало.
P:asc exec distinct type from myTable;
pvt:exec P#(type!val) by date,sym from myTable;
Ответ №1:
Я думаю, что проблема, с которой вы можете столкнуться, связана с присвоением имени столбцу type
. Ключевые слова или типы ошибок не могут использоваться при назначении переменных, поэтому вы можете захотеть это изменить.
С точки зрения фактического кода, это, кажется, работает нормально для меня с измененным именем столбца.
q)myTable:([]date:2020.01.02;sym:`ABC`ABC`ANX`XYZ`XYZ;typ:``a2``a3`a2;val:100 200 300 400 100)
q)P:`$"type_",/:asc exec string distinct typ from myTable
q)0!0^exec P#((`$"type_",/:string[typ])!val) by date,sym from myTable
date sym type_ type_a2 type_a3
------------------------------------
2020.01.02 ABC 100 200 0
2020.01.02 ANX 300 0 0
2020.01.02 XYZ 0 100 400
Я использовал 0^
здесь, чтобы заполнить все нулевые записи таблицы 0 и 0!
отменить ввод таблицы.
Комментарии:
1. Спасибо, я попробовал ваш код, и он работает с вашей таблицей, но когда я переключился на свою таблицу, я получил ошибку «длина». Я попробовал
exec P#(trdType!val) by date,sym from
datesym xasc myTable;
и получил таблицу в нужном формате, но все пусто, кроме столбцов date и sym. Я попытался добавить 0!0 ^ и все равно 0
Ответ №2:
Обратите внимание, что не рекомендуется называть столбцы ключевыми словами (вы теряете возможность использовать QSql), но вы все равно можете обойти это с помощью функциональной формы:
q)table:flip `date`sym`type`val!(2020.01.02;`ABC`ABC`ANX`XYZ`XYZ;``a2``a3`a2;100 200 300 400 100)
q)parse"update `null^type from table"
!
`table
()
0b
(,`x)!,(^;,`null;@:)
q)table:![table;();0b;enlist[`type]!enlist(^;enlist`null;`type)]
q)P:`$?[table;();();(string;(distinct;`type))]
q)0!0^?[table;();{x!x}`date`sym;(#;`P;(!;`type;`val))]
date sym null a2 a3
---------------------------
2020.01.02 ABC 100 200 0
2020.01.02 ANX 300 0 0
2020.01.02 XYZ 0 100 400
q)`date`sym`type_null`type_a2`type_a3 xcol 0!0^?[table;();{x!x}`date`sym;(#;`P;(!;`type;`val))]
date sym type_null type_a2 type_a3
----------------------------------------
2020.01.02 ABC 100 200 0
2020.01.02 ANX 300 0 0
2020.01.02 XYZ 0 100 400
Применение синтаксического анализа к оператору QSql, записанному в виде строки, вернет внутреннее представление функциональной формы.
Ответ №3:
Более общая функция pivot (здесь ) работает из коробки и даже работает с вашим столбцом с именем type …. хотя, как говорили другие, вам определенно следует избегать столбца с именем type .
q)myTable:flip`date`sym`type`val!(5#2020.01.02;`ABC`ABC`ANX`XYZ`XYZ;``a2``a3`a2;100 200 300 400 100)
q)0^piv[myTable;`date`sym;1#`type;`val;{`$raze each"type_",/:string`null^y};{x,z}]
date sym| type_null type_a2 type_a3
--------------| -------------------------
2020.01.02 ABC| 100 200 0
2020.01.02 ANX| 300 0 0
2020.01.02 XYZ| 0 100 400