在Google BigQuery中汇总时是否可以运行计算

时间:2019-06-29 13:02:28

标签: mysql google-bigquery

在StandardSQL中,是否可以在分组过程中在每一行上运行操作?我不确定我是否在问正确的问题。这是一个例子。

假设我有3行:

annotations

我现在想按move_id对表进行分组,并根据每行的数量与最小数量的比例求和。

例如,最小数量为10,第2行的数量为20,这意味着在求和之前应将其值减半。第3行的数量为30,这意味着在求和之前,它的值应减少为三分之一。

因此,我的最终值列应为100 +(150/2)+(200/3)= 241.67。

我的结果应该是:

| move_id | item_id | quantity | value |
|---------|---------|----------|-------|
| 1       | 1       | 10       | 100   |
| 1       | 2       | 20       | 150   |
| 1       | 3       | 30       | 200   |

查询应类似于:

| move_id | quantity | value  |
|---------|----------|--------|
| 1       | 10       | 241.67 |

这可能吗?

3 个答案:

答案 0 :(得分:1)

以下内容适用于BigQuery Standard SQL,一次即可完成

#standardSQL
SELECT move_id, 
  MIN(quantity) AS quantity, 
  SUM(value/quantity) * MIN(quantity) AS value
FROM `project.dataset.table`
GROUP BY move_id  

如果要应用于您的问题的样本数据-结果为

Row move_id quantity    value    
1   1       10          241.66666666666669     

您将在此处看到-与在查询中拆分计算/汇总不同,您可以像下面这样更改公式

  • 100 +(150/2)+(200/3)

  • (100 * 10/10 +(150 * 10/20)+(200 * 10/30)

  • (((100/100 +(150/20)+(200/30))* 10

  • SUM(价值/数量)* MIN(数量)

因此,您最终只能进行一次简单的聚合

答案 1 :(得分:0)

查询中有些困难的部分是您想要汇总,但是您要记住的总和本身就需要汇总的结果-每个quantity组的最小move_id。一种选择是首先在CTE中生成最小值quantity,然后使用您的逻辑汇总该CTE。

WITH cte AS (
    SELECT *, MIN(quantity) OVER (PARTITION BY move_id) min_quantity
    FROM yourTable
)

SELECT
    move_id,
    MIN(quantity) AS quantity,
    SUM(value * min_quantity / quantity) AS value
FROM cte
GROUP BY
    move_id;

enter image description here

Demo

注意:上面的演示使用了SQL Server,但是所使用的SQL符合ANSI,并且也应该在BigQuery上运行而没有任何问题。

此外,如果您的BigQuery版本不支持cte,则您可以仅内嵌CTE中包含的代码作为子查询。

答案 2 :(得分:0)

在没有CTE的情况下,您可以使用Derived Table(子查询)分别获取每个move_id的最小数量。然后,在主查询中利用它们来计算总和:

SELECT t.move_id,
       dt.min_quantity,
       Sum(t.value / ( t.quantity / dt.min_quantity )) AS value
FROM   your_table AS t
       JOIN (SELECT move_id,
                    Min(quantity) AS min_quantity
             FROM   your_table
             GROUP  BY move_id) AS dt
         ON dt.move_id = t.move_id
GROUP  BY t.move_id  

SQL Fiddle Demo