Its a little slower, but generalizes the solution a bit.
func:{[td] c:where 0=type each flip td; / find which columns need unpacked
ocn:cols td; / store all original column names for order
ncn:`$raze{string[x],/:string 1+til count first each flip[y]x}[;td]each(),c; / calculate new column names
acn:ncn,ocn except c; / list of all final columns
c:raze {x where x like y}[acn;]each string[ocn],'"*"; / all final columns in order flip
c!flip raze each td / create final table with column names and column data }
q)t
a b
----------
1 4
5 6
2 6
12 23
3 12
36 14
q)func t
a b1 b2 b3
----------
1 4 5 6
2 6 12 23
3 12 36 14
q)t3
a b c d
------------------
1 4 5 6
1 1 2 3
2 6 12 23
2 4 5 6
3 12 36 14
3 7 8 9
q)func t3
a b1 b2 b3 c d1 d2 d3
---------------------
1 4 5 6 1 1 2 3
2 6 12 23 2 4 5 6
3 12 36 14 3 7 8 9