Сложный список списка пустых символов в столбце в kdb - PullRequest
0 голосов
/ 28 июня 2019

У меня есть объединенная таблица, которая состоит из списка списка символов.

q)t:([] a:`c`d; b:("";"fill"));
q)s:([] a:`b`c`c; b:("";"";""))
q)select from t lj select b by a from s
Output:
a b
---------
c ("";"") / This is the culprit want to replace it with null character
d "fill"

Вывод объединения состоит из списка списка пустых символов.Я хочу заменить это пустым символом.

Expected output:
     a b
    ---------
    c "" 
    d "fill"

Пробовал: несколько неудачных попыток

q)update b:?[null in b;raze b;b]from select from t lj select b by a from s 
q)update b:?["" in b;raze b;b]from select from t lj select b by a from s

Ответы [ 3 ]

2 голосов
/ 28 июня 2019

Чтобы заменить список списка пустых строк пустой строкой, вы можете попробовать выполнить следующий запрос:

q) select from t lj  select (b;"")all""~/:b by a from s

Выход:

a b     
--------
c ""    
d "fill"

Пояснение:

По сути, список пустых строк исходит из команды group в правой таблице. Поэтому на этапе группировки мы можем сопоставить, если все элементы в сгруппированном списке (b column values) для определенного значения a являются пустой строкой. И если они просто заменяют их одной пустой строкой.

q) select (b;"")all""~/:b by a from s
a| b 
-| --
b| ""
c| ""

Для a = c, b сгруппированными значениями являются (""; ""). Давайте разберем команду:

q) b:("";"")
q) ""~/:b  / output 11b
q) all ""~/:b  / output 1b
q)(b;"") all ""~/:b  / output ""

Последняя команда - индексирование списка. Если результат предыдущей команды равен 1b, что означает, что все элементы являются пустыми строками, тогда возвращается "", иначе возвращается фактический b.

Edit:

Исходя из обсуждения в разделе комментариев ответа TerryLynch, похоже, что ваше требование:

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

Для этого вы можете использовать следующий запрос:

q) select from t lj select b:raze ("";b except enlist "") by a from s

Но это привело бы к различным типам для разных значений в столбце b. Пустая строка будет 10h, а весь список непустых строк будет 0h.

Для согласованного типа можно использовать приведенный ниже запрос, который возвращает enlist"" вместо "", но это не будет пустой строкой:

q) select from t lj select b:{(c;enlist "")()~c:x except enlist ""}b by a from s
1 голос
/ 28 июня 2019

Вместо того, чтобы пытаться исправить неблагоприятный результат, я думаю, вам нужно решить, что вы хотите сделать с дублирующимися строками c в таблице s. Вы группируете по столбцу a, но у него есть дубликаты, так как он должен себя вести ... должен ли он принимать первое значение, должен ли он принимать последнее значение? Должен ли он добавить две строки вместе? Если вы решите это, то избежите этой проблемы, например:

q)t lj select last b by a from s
a b
--------
c ""
d "fill"
1 голос
/ 28 июня 2019

Альтернативным решением будет просто raze все результаты b вместе. Меньше where предложений в использовании и меньше совпадений (~).

q)update raze'/[b] from (t lj select b by a from s)
a b
--------
c ""
d "fill"

Здесь я использовал более неизвестный уровень зачисления, как предварительную оценку, а затем применил его к каждой строке из lj. Для вашего случая, даже более быстрое решение будет

update raze each b from (t lj select b by a from s)

Это даст результаты, отличные от ответов Рахулса

q)update raze each b from (t lj select b by a from s)
a b
--------
c "str"
d "fill"
q) select from t lj  select (b;"")all""~/:b by a from s
a b
------------
c ("";"str")
d "fill"
q)update raze each b from (t lj select b by a from s)
a b
--------
c "str"
d "fill"
...