Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google bigquery bigquery标准中按汇总分组的分组函数_Google Bigquery - Fatal编程技术网

Google bigquery bigquery标准中按汇总分组的分组函数

Google bigquery bigquery标准中按汇总分组的分组函数,google-bigquery,Google Bigquery,我知道bigquery遗留SQL有一个grouping()函数,用于按汇总分组以区分空值 标准SQL是否有类似的函数?或者有没有其他方法可以在不首先用硬编码值替换的情况下区分空值?根据文档,可以在StandardSQL中找到。其定义如下: GROUP BY ROLLUP返回GROUP BY对 汇总列表中的表达式,每个表达式都称为分组 设置对于汇总列表(a、b、c),分组集为(a、b、c), (a,b),(a),() 您可以按如下语法使用它: SELECT * FROM `project_id.

我知道bigquery遗留SQL有一个grouping()函数,用于按汇总分组以区分空值


标准SQL是否有类似的函数?或者有没有其他方法可以在不首先用硬编码值替换的情况下区分空值?

根据文档,可以在StandardSQL中找到。其定义如下:

GROUP BY ROLLUP返回GROUP BY对 汇总列表中的表达式,每个表达式都称为分组 设置对于汇总列表(a、b、c),分组集为(a、b、c), (a,b),(a),()

您可以按如下语法使用它:

SELECT * FROM `project_id.dataset.table`
GROUP BY ROLLUP (column)
此外,为了清楚地解释功能,我将使用以下示例(取自文档):

以及产量,

+------+------+-------+
| sku  | day  | total |
+------+------+-------+
| NULL | NULL | 39.77 |
|  123 | NULL | 28.97 |
|  123 |    1 | 18.98 |
|  123 |    2 |  9.99 |
|  456 | NULL |  8.81 |
|  456 |    1 |  4.56 |
|  456 |    3 |  4.25 |
|  789 |    3 |  1.99 |
|  789 | NULL |  1.99 |
+------+------+-------+
Row sku day sum_per_sku_per_day sum_per_sku sum_all_days_sku
1   123 1   18.98               28.97       39.77
2   456 1   4.56                8.81        39.77
3   123 2   9.99                28.97       39.77
4   789 3   1.99                1.99        39.77
5   456 3   4.25                8.81        39.77
Row sku  day  total
1   null null 39.53
2   null null 5
3   null 3    5
4   123  null 28.97
5   123  1    18.98
6   123  2    9.99
7   456  null 4.56
8   456  1    4.56
9   789  null 1
10  789  3    1
 
Row sku  day  total
1   null null 39.53
2   0    null 5
3   0    3    5
4   123  null 28.97
5   123  1    18.98
6   123  2    9.99
7   456  null 4.56
8   456  1    4.56
9   789  null 1
10  789  3    1
输出可分为三部分进行说明

  • sku
    为空且日期为空时
  • 它是指所有
    sku
    day
    值的总和。在此示例中,所有日期和sku中所有价格的总和为39.77

  • sku
    不为空且
    day
    为空时
  • 它是指特定的
    sku
    在所有
    天内的总和。例如,当
    sku=123
    时,所有天数的总和为28.97

  • 日期
    sku
    均不为空时。
  • 它就像一个正常的总和和分组。它显示特定值对的和

    关于第二个问题,如果要更改空值,可以相应地更改每个空值或使用其他方法。下面我使用了以不同的方式输出相同的结果

    WITH Sales AS (
          SELECT 123 AS sku, 1 AS day, 9.99 AS price UNION ALL
          SELECT 123, 1, 8.99 UNION ALL
          SELECT 456, 1, 4.56 UNION ALL
          SELECT 123, 2, 9.99 UNION ALL
          SELECT 789, 3, 1.00 UNION ALL
          SELECT 456, 3, 4.25 UNION ALL
          SELECT 789, 3, 0.99
    ),
    sum_all AS (
    SELECT sum(price) as sum_all_days_sku from Sales
    ),
    sum_per_sku AS (
    SELECT sku, ROUND(sum(price),2) AS sum_per_sku, CONCAT("This sum refers to sku =", sku) AS comment FROM Sales GROUP BY sku
    ),
    sum AS (
    SELECT sku, day, sum(price) AS sum_per_sku_per_day FROM Sales GROUP BY sku, day
    )
    SELECT a.sku,a.day,a.sum_per_sku_per_day, b.sum_per_sku, c.sum_all_days_sku 
    FROM sum a LEFT JOIN sum_per_sku b USING(sku) CROSS JOIN sum_all c
    
    以及产量,

    +------+------+-------+
    | sku  | day  | total |
    +------+------+-------+
    | NULL | NULL | 39.77 |
    |  123 | NULL | 28.97 |
    |  123 |    1 | 18.98 |
    |  123 |    2 |  9.99 |
    |  456 | NULL |  8.81 |
    |  456 |    1 |  4.56 |
    |  456 |    3 |  4.25 |
    |  789 |    3 |  1.99 |
    |  789 | NULL |  1.99 |
    +------+------+-------+
    
    Row sku day sum_per_sku_per_day sum_per_sku sum_all_days_sku
    1   123 1   18.98               28.97       39.77
    2   456 1   4.56                8.81        39.77
    3   123 2   9.99                28.97       39.77
    4   789 3   1.99                1.99        39.77
    5   456 3   4.25                8.81        39.77
    
    Row sku  day  total
    1   null null 39.53
    2   null null 5
    3   null 3    5
    4   123  null 28.97
    5   123  1    18.98
    6   123  2    9.99
    7   456  null 4.56
    8   456  1    4.56
    9   789  null 1
    10  789  3    1
     
    
    Row sku  day  total
    1   null null 39.53
    2   0    null 5
    3   0    3    5
    4   123  null 28.97
    5   123  1    18.98
    6   123  2    9.99
    7   456  null 4.56
    8   456  1    4.56
    9   789  null 1
    10  789  3    1
    
    如图所示,输出与GROUP BY ROLLUP()的总和相同。但是,它以列的形式显示

    更新:

    如果部分
    sku
    行为空,如果在使用ROLLUP()之前不处理空值,就会有点混乱

    使用下面的示例数据和查询

    WITH Sales AS (
      SELECT 123 AS sku, 1 AS day, 9.99 AS price UNION ALL
      SELECT 123, 1, 8.99 UNION ALL
      SELECT 456, 1, 4.56 UNION ALL
      SELECT 123, 2, 9.99 UNION ALL
      SELECT 789, 3, 1.00 UNION ALL
      SELECT null, 3, 1 UNION ALL
      SELECT null, 3, 1 UNION ALL
      SELECT null, 3, 1 UNION ALL
      SELECT null, 3, 1 UNION ALL
      SELECT null, 3, 1
    )
    SELECT
      sku,
      day,
      SUM(price) AS total
    FROM Sales
    GROUP BY ROLLUP(sku, day)
    ORDER BY sku, day;
    
    注意,有5行
    sku
    NULL
    ,引用和为5。以及产量,

    +------+------+-------+
    | sku  | day  | total |
    +------+------+-------+
    | NULL | NULL | 39.77 |
    |  123 | NULL | 28.97 |
    |  123 |    1 | 18.98 |
    |  123 |    2 |  9.99 |
    |  456 | NULL |  8.81 |
    |  456 |    1 |  4.56 |
    |  456 |    3 |  4.25 |
    |  789 |    3 |  1.99 |
    |  789 | NULL |  1.99 |
    +------+------+-------+
    
    Row sku day sum_per_sku_per_day sum_per_sku sum_all_days_sku
    1   123 1   18.98               28.97       39.77
    2   456 1   4.56                8.81        39.77
    3   123 2   9.99                28.97       39.77
    4   789 3   1.99                1.99        39.77
    5   456 3   4.25                8.81        39.77
    
    Row sku  day  total
    1   null null 39.53
    2   null null 5
    3   null 3    5
    4   123  null 28.97
    5   123  1    18.98
    6   123  2    9.99
    7   456  null 4.56
    8   456  1    4.56
    9   789  null 1
    10  789  3    1
     
    
    Row sku  day  total
    1   null null 39.53
    2   0    null 5
    3   0    3    5
    4   123  null 28.97
    5   123  1    18.98
    6   123  2    9.99
    7   456  null 4.56
    8   456  1    4.56
    9   789  null 1
    10  789  3    1
    
    如上所示,第二和第三个输出的行与空值相关,而不是与
    ROLLUP()
    的输出相关。为了区分它,在最终查询中使用这些值之前,必须先处理这些值。特别是,我在
    sku
    为空的地方指定了零。然后查询数据,如下所示:

    WITH Sales AS (
      SELECT 123 AS sku, 1 AS day, 9.99 AS price UNION ALL
      SELECT 123, 1, 8.99 UNION ALL
      SELECT 456, 1, 4.56 UNION ALL
      SELECT 123, 2, 9.99 UNION ALL
      SELECT 789, 3, 1.00 UNION ALL
      SELECT null, 3, 1 UNION ALL
      SELECT null, 3, 1 UNION ALL
      SELECT null, 3, 1 UNION ALL
      SELECT null, 3, 1 UNION ALL
      SELECT null, 3, 1
    ), 
    data as (
    SELECT IFNULL(sku , 0) as sku, day, price from Sales
    )
    SELECT
      sku,
      day,
      SUM(price) AS total
    FROM data
    GROUP BY ROLLUP(sku, day)
    ORDER BY sku, day;
    
    以及产量,

    +------+------+-------+
    | sku  | day  | total |
    +------+------+-------+
    | NULL | NULL | 39.77 |
    |  123 | NULL | 28.97 |
    |  123 |    1 | 18.98 |
    |  123 |    2 |  9.99 |
    |  456 | NULL |  8.81 |
    |  456 |    1 |  4.56 |
    |  456 |    3 |  4.25 |
    |  789 |    3 |  1.99 |
    |  789 | NULL |  1.99 |
    +------+------+-------+
    
    Row sku day sum_per_sku_per_day sum_per_sku sum_all_days_sku
    1   123 1   18.98               28.97       39.77
    2   456 1   4.56                8.81        39.77
    3   123 2   9.99                28.97       39.77
    4   789 3   1.99                1.99        39.77
    5   456 3   4.25                8.81        39.77
    
    Row sku  day  total
    1   null null 39.53
    2   null null 5
    3   null 3    5
    4   123  null 28.97
    5   123  1    18.98
    6   123  2    9.99
    7   456  null 4.56
    8   456  1    4.56
    9   789  null 1
    10  789  3    1
     
    
    Row sku  day  total
    1   null null 39.53
    2   0    null 5
    3   0    3    5
    4   123  null 28.97
    5   123  1    18.98
    6   123  2    9.99
    7   456  null 4.56
    8   456  1    4.56
    9   789  null 1
    10  789  3    1
    

    请注意,现在更容易理解,因为我们知道
    0
    表示空数据。

    如果group by rollup之前的初始表(sku为空)中已经存在空值,会发生什么情况。有没有办法区分源空值和求和空值?@Rendell1,我已经更新了我的答案,并做了进一步的解释。请考虑接受和投票的答案。我希望有一种方法,没有硬编码的价值。如果我事先不知道列的可能值,这可能会适得其反。但我想不出其他解决办法,所以我会给你答案。非常感谢。