Arrays BigQuery-在数组内生成时重复的随机数

Arrays BigQuery-在数组内生成时重复的随机数,arrays,random,google-bigquery,nested,Arrays,Random,Google Bigquery,Nested,我做了一个BigQuery查询,其中包括为每一行生成一个随机数数组。我使用随机数来决定从源表中存在的数组中包含哪些元素 我很难让随机数数组在每一行上都不重复。我找到了解决办法,但这是预期的行为吗?我将在下面发布两种方法,一种是理想的结果,另一种是糟糕的结果。请注意,如果不使用数组,而只生成一个随机数,则这两种方法都可以正常工作 方法1不良结果: SELECT ( SELECT ARRAY( SELECT AS STR

我做了一个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子句的子查询)的结果重用率不应该低于选择正常值吗?人们有时会谈论子查询的性能问题,因为假设每行计算一次,即使结果可能相同

你同意这似乎是一个bug吗

下面的示例表明,问题不一定是创建一个随机数组——即使执行一个子选择,其中恰好有一个不相关的数组,也会导致RAND出现问题。通过消除子选择、仅从子选择中选择随机值,或者在数组中包含一个按行变化的值,问题就解决了。奇怪

坏的

修正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

我不明白为什么第一个查询不起作用,但我有一个更简单的版本适合您:

选择 选择“阵列加总为随机” 从Unnest生成数组0、10、1作为时间 作为随机的\u次 从UNNESTGENERATE_阵列0、10、1
更新:我后来意识到问题出在ARRAYsubquery上,只要你能避免像我上面的查询那样在你的案例中使用它,你应该会没事的。

谢谢@Yun Zhang。我在上面发布了一些额外的细节。我认为你关于子查询的说法可能是正确的,但是我发现了一些新的有趣的案例,如上所述。我同意你提出的新案例是奇怪的,或者更正式地说,是不一致的。
SELECT
    (SELECT AS STRUCT RAND() AS r, ARRAY(SELECT u) AS a).r
FROM UNNEST(GENERATE_ARRAY(0, 5, 1)) AS u