JSLover
JSLover

Reputation: 165

"lateral join" equivalent in KDB?

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

Answers (2)

Thomas Smyth
Thomas Smyth

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

Alex R.
Alex R.

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

Related Questions