Google bigquery 一次对多个列执行BigQuery RANK()

Google bigquery 一次对多个列执行BigQuery RANK(),google-bigquery,Google Bigquery,我在BigQuery中有一个表,其结构如下: my_表 name num1 num2 num3 num4 joe 12 15 11 8 tom 15 18 13 11 bill 19 11 12 23 nick 27 13 16 15 sal 9 12 16 5 chris 13

我在BigQuery中有一个表,其结构如下:

my_表

name    num1    num2    num3    num4
joe     12      15      11      8
tom     15      18      13      11
bill    19      11      12      23
nick    27      13      16      15
sal      9      12      16      5
chris   13      19      25      23
并希望创建4个附加列,每个列输出4个num*列中的1个列的秩。我的目标是:

name    num1    num2    num3    num4    num1_rk    num2_rk    num3_rk    num4_rk
joe     12      15      11      8       2          4          ...
tom     15      18      13      11      4          5
bill    19      11      12      23      5          1
nick    27      13      16      15      6          3
sal      9      12      16      5       1          2
chris   13      19      25      23      3          6
我可以通过将
SELECT
调用中的
RANK()
函数应用于4列中的每一列来实现以下目标,但是这并不适合我的用例

SELECT
  *,
  RANK() OVER (ORDER BY num1 ASC) AS num1_rank,
  RANK() OVER (ORDER BY num2 ASC) AS num2_rank,
  ...
FROM my_table

我有一个非常宽泛的表格,有50多个(而且还在上升)指标,每个指标都需要排名。有没有一种方法可以做到这一点,而不必将PERCENT_RANK()列应用50多次?

下面是最接近您要求的方法

#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   
有输出


我认为最好的方法是将我的表从宽表转换为长表,然后在应用
百分比秩时对不同的度量进行分区,然后再转换回宽表。