I want to clone all rows from a Kdb table for each set of selected columns from the same table. I couldn’t find the best way to describe what I want to achieve. The example below should clarify what I want to do:
I need a shortcut function to convert tab to tab2. I have used joins to achieve this; but this solution is not scalable as I might get more columns x4, x5 etc.that I would I need to add to ‘x’ and querying table again and again in each join clause will also affect performance.
The operation you are describing sounds like unpivoting a table, the following function will achieve that for your example. To make it more generic you will need to make any columns that need to be ungrouped the values in your keyed table.
One way you could go about doing it that should be reasonably more scalable is through the use of a functional select. For the sake of clarity I’ve increased both the number of rows and columns in order to show the difference in performance between the methods. There may be faster ways than this to achieve what you’re looking for but this is a cleaner/more scalable version of the code to begin with,
q)\t t2:(select a,x:x1 from tab),(select a,x:x2 from tab),(select a,x:x3 from tab),(select a,x:x4 from tab),(select a,x:x5 from tab),(select a,x:x6 from tab),(select a,x:x7 from tab)
I should note here that Thomas’ answer will also work (all required rows will be in the table) but it’s formatted differently and less performant on larger datasets. i.e for the same example
q)\t ungroup{enlist[`x]!enlist value x}each 1!tab
2795
I’d be interested to see any faster implementations. Hope this helps somewhat.
The operation you are describing sounds like unpivoting a table, the following function will achieve that for your example. To make it more generic you will need to make any columns that need to be ungrouped the values in your keyed table.
This is using the fact that we operate right to left (to name the columns you want to apply to xx1 etc. as n) and the each-both operator to project the column names (1_cols tab) and the unique indices you wanted into the variables z and k.
this can be performed with a generalized unpivot function:
unpivot:{ungroup (x!(key;value)@:) each y}
you supply the desired key and value column names as the x parameter and a table who’s key defines the columns to repeat as the y parameter. the values in the key column retain the column names from which they came.
Thanks! It indeed helped. I realized later that I would need multiple key columns (like column a) instead of just one. I did below modification to the query to make it work: