#arrays #random #google-bigquery #nested
# #массивы #Случайный #google-bigquery #вложенные
Вопрос:
Я сделал запрос BigQuery, который включает в себя генерацию массива случайных чисел для каждой строки. Я использую случайные числа, чтобы решить, какие элементы включить из массива, существующего в моей исходной таблице.
У меня было много проблем с тем, чтобы массивы случайных чисел не повторялись в каждой отдельной строке. Я нашел обходной путь, но является ли это ожидаемым поведением? Ниже я опубликую два «метода» (один с желаемыми результатами, другой с плохими результатами). Обратите внимание, что оба метода отлично работают, если вы не используете массив, а просто генерируете одно случайное число.
Метод 1 (ПЛОХИЕ результаты):
SELECT
(
SELECT
ARRAY(
SELECT AS STRUCT
RAND() AS random
FROM UNNEST(GENERATE_ARRAY(0, 10, 1)) AS _time
) AS random_for_times
)
FROM UNNEST(GENERATE_ARRAY(0, 10, 1))
Метод 2 (ХОРОШИЕ результаты):
SELECT
(
SELECT
ARRAY(
SELECT AS STRUCT
RAND() AS random
FROM UNNEST(GENERATE_ARRAY(0, 10, 1)) AS _time
) AS random_for_times
FROM (SELECT NULL FROM UNNEST([0]))
)
FROM UNNEST(GENERATE_ARRAY(0, 10, 1))
Пример результатов — Метод 1 (НЕВЕРНЫЙ):
Row 1
0.5431173080158003
0.5585452983410205
...
Row 2
0.5431173080158003
0.5585452983410205
...
Пример результатов — Метод 2 (ХОРОШИЙ):
Row 1
0.49639706531271377
0.1604380522058521
...
Row 2
0.7971869432989377
0.9815667330115473
...
РЕДАКТИРОВАТЬ: смотрите Ниже некоторые альтернативные примеры, которые похожи, после теории Юнь Чжана о подзапросах. Ваше решение было полезно для проблемы, которую я опубликовал, но обратите внимание, что все еще есть некоторые случаи, которые я нахожу непонятными. Кроме того, хотя я согласен, что вы, вероятно, правы в отношении того, что подзапросы привязаны к проблеме: не должен ли подзапрос (особенно без предложения FROM) с меньшей вероятностью повторно использовать его результаты, чем выбор «нормального» значения? Иногда люди говорят о проблемах с производительностью подзапросов, потому что они предположительно вычисляются один раз для каждой строки, даже если результаты могут быть одинаковыми.
Согласны ли вы с тем, что это может быть ошибкой?
Приведенные ниже примеры показывают, что проблема не обязательно даже в создании массива случайных чисел — даже выполнение подвыборки, в которой просто случайно есть несвязанный массив, может вызвать проблемы с RAND() . Проблема устраняется путем устранения подвыбора, путем выбора только случайного значения из подвыбора или путем включения значения внутри массива, которое варьируется в зависимости от строки. Странно !!!
ПЛОХО
SELECT
(SELECT AS STRUCT RAND() AS r, ARRAY(SELECT 1) AS a)
FROM UNNEST(GENERATE_ARRAY(0, 5, 1)) AS u
ИСПРАВЛЕНИЕ # 1 — нет подвыбора
SELECT
STRUCT(RAND() AS r, ARRAY(SELECT 1) AS a)
FROM UNNEST(GENERATE_ARRAY(0, 5, 1)) AS u
ИСПРАВЛЕНИЕ # 2 — выберите только r
SELECT
(SELECT AS STRUCT RAND() AS r, ARRAY(SELECT 1) AS a).r
FROM UNNEST(GENERATE_ARRAY(0, 5, 1)) AS u
Исправление # 3 — Массив содержит «u»
SELECT
(SELECT AS STRUCT RAND() AS r, ARRAY(SELECT u) AS a).r
FROM UNNEST(GENERATE_ARRAY(0, 5, 1)) AS u
Ответ №1:
Не понял, почему первый запрос не сработал, но у меня есть более простая версия, которая работает для вас:
SELECT (
SELECT array_agg(RAND()) AS random
FROM UNNEST(GENERATE_ARRAY(0, 10, 1)) AS _time
) AS random_for_times
FROM UNNEST(GENERATE_ARRAY(0, 10, 1))
Обновление: позже я понял, что проблема в ARRAY(subquery)
том, что до тех пор, пока вы можете избежать использования его в вашем случае (как в моем запросе выше), все должно быть в порядке.
Комментарии:
1. Спасибо @Yun Zhang. Я опубликовал некоторые дополнительные детали в качестве изменений выше. Я думаю, что вы можете быть правы насчет подзапросов, но я нашел несколько новых интересных случаев, как отмечалось выше.
2. Я согласен с вами в том, что новые случаи, которые вы привели, являются странными (или, более формально говоря, непоследовательными).