3

I want to add a new column to a kdb table, it should add based of the existing column by populating with the non null value as below

q)t:([]a:`a`b`c`d`e`f`g`h;b:1 0n 3 4 0n 6 0n 8;c:0n 2 0n 0n 5 0n 7 0n)
q)t
a b c
-----
a 1  
b   2
c 3  
d 4  
e   5
f 6  
g   7
h 8  

I want to add a column d that would take the value from c or d that isn't null to produce a table like this

a b c d
-------
a 1   1
b   2 2
c 3   3
d 4   4
e   5 5
f 6   6
g   7 7
h 8   8

I tried concatenating but then it has the null in it:

q)update d:(b,'c)from t
a b c  d  
----------
a 1    1  
b   2    2
c 3    3  
d 4    4  
e   5    5
f 6    6  
g   7    7
h 8    8  

4 Answers 4

5

A vector conditional might be what you’re after, something like the below:

update d:?[null b;c;b] from t

You can read more about vector conditionals here. This expects a Boolean list as the first argument and returns values from a list in the second argument where True, or values from a list in the third argument where False. For example:

q)?[10101b;”abcde”;”ABCDE”]
“aBcDe”

When used in conjunction with a select/update statement, columns of the table can be specified as the arguments to the vector conditional as these are simply lists.

As an aside, the null keyword returns a Boolean true where a value is null and is useful as part of your solution.

Sign up to request clarification or add additional context in comments.

Comments

3

You can use the ^(fill) operator.

t:([]a:`a`b`c`d`e`f`g`h;b:1 0n 3 4 0n 6 0n 8;c:0n 2 0n 0n 5 0n 7 0n)
q)update d:b^c from t
a b c d
-------
a 1   1
b   2 2
c 3   3
d 4   4
e   5 5
f 6   6
g   7 7
h 8   8

It is worth noting that if you had a row with non-null values for b and c then the query above would default to the value in c. If you would prefer the value in b to be default then switch the inputs:

q)t:([]a:`a`b`c`d`e`f`g`h;b:1 0n 3 4 0n 6 0n 8;c:0n 2 0n 0n 5 100 7 0n)
q)update d:b^c from t
a b c   d
-----------
a 1     1
b   2   2
c 3     3
d 4     4
e   5   5
f 6 100 100
g   7   7
h 8     8
q)update d:c^b from t
a b c   d
---------
a 1     1
b   2   2
c 3     3
d 4     4
e   5   5
f 6 100 6
g   7   7
h 8     8

Comments

0

You could use 'or(|)' operator.

  q)update d:b|c from t

Concat will give you a list with items from both 'b' and 'c' column. It will not remove null. 'or' will compare each pair of 'b' and 'c' and will return maximum value from that pair. As null is lesser than an integer, it will give you integer value either from 'b' or 'c' column.

Comments

0

Can use fill here - https://code.kx.com/wiki/Reference/Caret

q)t:([]a:`a`b`c`d`e`f`g`h;b:1 0n 3 4 0n 6 0n 8;c:0n 2 0n 0n 5 0n 7 0n)
q)update d:c^b from t
a b c d
-------
a 1   1
b   2 2
c 3   3
...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.