Reputation: 165
How do you "unpack" an array valued column in kdb ?
I have a table T which includes an array-valued column C, and want a result with each the rows of T duplicated as many times as it has entries in the column C, with each duplicate containing one of the values from that column.
In PostgreSQL this would be a "lateral join".
Upvotes: 1
Views: 423
Reputation: 5644
The simplest way to flatten nested columns is with the ungroup
command. This command will work where multiple nested columns exist, provided the lists in each row have the same length.
q)show tab:([]a:`a`b`c;b:(1#`d;`e`f;`g`h);c:(1#1;2 3;4 5))
a b c
----------
a ,`d ,1
b `e`f 2 3
c `g`h 4 5
q)ungroup tab
a b c
-----
a d 1
b e 2
b f 3
c g 4
c h 5
The downsides to this approach are that all nested columns are ungrouped and if there are different length lists in each row then the command will fail:
q)show tab2:([]a:`a`b`c;b:(1#`d;`e`f;`g`h);c:(1#1;2 3;1#4))
a b c
----------
a ,`d ,1
b `e`f 2 3
c `g`h ,4 / different length lists
q)ungroup tab2
'length
[0] ungroup tab2
^
One possible solution to ungroup by a single column is the following, which duplicates each row by the number of elements in each c
value:
q)f:{[t;c]@[t where count each r;c;:;raze r:t c]}
q)f[tab2;`c]
a b c
--------
a ,`d 1
b `e`f 2
b `e`f 3
c `g`h 4
Upvotes: 1
Reputation: 721
Assuming you have the following table:
t:([]a:`a`b`c`d;b:(1,();(2;3);4,();(5;6;7)))
t
a b
-------
a ,1
b 2 3
c ,4
d 5 6 7
And you want duplicated rows for each value in column b, you can use UNGROUP
to get:
q) ungroup t
a b
---
a 1
b 2
b 3
c 4
d 5
d 6
d 7
Upvotes: 4