Ниже самое близкое к тому, что вы запрашиваете
#standardSQL
SELECT * FROM my_table JOIN (
SELECT name, STRING_AGG(CAST(num_rank AS STRING) ORDER BY OFFSET) ranks
FROM (
SELECT name, OFFSET, RANK() OVER(PARTITION BY OFFSET ORDER BY CAST(num AS INT64)) AS num_rank
FROM my_table t,
UNNEST(SPLIT(REGEXP_REPLACE(FORMAT('%t', t), r'[() ]', ''))) num WITH OFFSET
WHERE OFFSET > 0
ORDER BY OFFSET
) GROUP BY name
) USING(name)
Если применить к выборке данных из вашего вопроса - вывод будет
Row name num1 num2 num3 num4 ranks
1 joe 12 15 11 8 2,4,1,2
2 tom 15 18 13 11 4,5,3,3
3 bill 19 11 12 23 5,1,2,5
4 nick 27 13 16 15 6,3,4,4
5 sal 9 12 16 5 1,2,4,1
6 chris 13 19 25 23 3,6,6,5
Как вы видите, выше делаетне зависеть от количества столбцов num - но ожидает, что они начнутся со секунды - это можно настроить на любые реальные данные, которые у вас есть
Кроме того, если вы хотите вывести ранги в виде массива вместо строки - вы можете использовать
ARRAY_AGG(num_rank ORDER BY OFFSET) ranks
вместо
STRING_AGG(CAST(num_rank AS STRING) ORDER BY OFFSET) ranks
с выходом