BigQuery RANK () для нескольких столбцов одновременно - PullRequest
1 голос
/ 30 октября 2019

У меня есть таблица в BigQuery следующей структуры:

my_table

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 дополнительных столбца, каждый из которых выдает ранг 1 из4 числа * столбцы. Тогда моя цель:

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

Я могу добиться следующего, применив функцию RANK() в вызове SELECT к каждому из 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 раз?

1 Ответ

2 голосов
/ 30 октября 2019

Ниже самое близкое к тому, что вы запрашиваете

#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   

с выходом

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...