Существует ли BigQuery, эквивалентный numpy .digitize? - PullRequest
1 голос
/ 27 января 2020

Я пробую приведенный ниже код, но мой запрос превысил ограничения ресурсов даже после кластеризации по t2.min и t2.max

select t1.myint64, t2.myindex
from t1, t2
where t1.myint64 between t2.min  and t2.max

Вот схема t1 ...

myint64            INTEGER        NULLABLE     

... и как выглядит таблица t1:

myint64    
 464578733234443
 756557774664663
 315676667544877
 485675445434553
 864664656568335
       ...
 464676656756776
         8857667
 866867887876666
 974244466724434
1025895506842623

[5876218 rows x 1 columns]

Вот схема t2 ...

Field name    Type        Mode    
myindex        INTEGER        NULLABLE
min            INTEGER        NULLABLE    
max            INTEGER        NULLABLE    

... и как выглядит таблица t2:

myindex               min                max
0                       0     70368744177663
1          70368744177664     87960930222079
2          87960930222080     96757023244287
3          96757023244288     97306779058175
4          97306779058176     97581656965119
...                   ...                ...
110544    919191720820736    923589767331839
110545    923589767331840    932385860354047
110546    932385860354048    949978046398463
110547    949978046398464    985162418487295
110548    985162418487296   1125899906842623

[110549 rows x 3 columns]

и желаемый результат:

myindex               myint64
 14456        464578733234443
 34355        756557774664663
  6465        315676667544877
 15354        485675445434553
 41455        864664656568335
                          ...
 14476        464676656756776
     0                8857667
 83444        866867887876666
 93545        974244466724434
110548       1025895506842623

[5876218 rows x 2 columns]

1 Ответ

2 голосов
/ 27 января 2020

Позвольте мне сделать предположение, что значение max действительно не нужно. То есть вы ищете первое значение "min" в table2.

. Позвольте мне также предположить, что table2 не очень велико.

Следующее может показаться громоздким, но он может делать то, что вы хотите:

select t1.*,
       (select min(minval)
        from unnest(t2.ar) minval
        where val >= minval
       ) as min
from table1 t1 cross join
     (select array_agg(t2.min order by min) as ar
      from table2 t2
     ) t2;

Если это работает, тогда вы можете присоединиться к table2, чтобы получить минимальное значение.

Почему это может работать лучше? По сути, BigQuery видит ваш запрос и решает, что ему нужно отправить много данных повсюду. При преобразовании table2 в массив только массив отправляется туда, где находятся данные table1. Затем unnest() является локальным для каждой записи в table1. По моему опыту, это может быть большой выигрыш в производительности.

РЕДАКТИРОВАТЬ:

Поскольку вы, похоже, ищете одно совпадение, другой метод состоит в чередовании двух таблиц, используйте накопительное окно функции, а затем фильтр:

with t as (
      select t1.myint64, null as t2min
      from t1
      union all
      select null, t2.min
      from t2
     )
select t.*
from (select t.*, max(t2min) over (order by coalesce(t2min, myint64)) as real_t2min
      from t
     ) t
where t2min is null;

Еще раз, если вам нужно max(), вы можете join вернуться к t2.

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