BigQuery 按条件平均列
BigQuery average column by condition
假设我在 BigQuery 中有以下简化数据:
WITH sales_log AS
(
SELECT 'John' as employee, 'ABC' client, 1234.56 sales, "phone" sale_type UNION ALL
SELECT 'John' as employee, 'ABC' client, 9857.56 sales, "online" sale_type UNION ALL
SELECT 'John' as employee, 'XYZ' client, 5678.56 sales, "phone" sale_type UNION ALL
SELECT 'John' as employee, 'XYZ' client, 64875.25 sales, "online" sale_type UNION ALL
SELECT 'Mary' as employee, 'ABC' client, 456.58 sales, "phone" sale_type UNION ALL
SELECT 'Mary' as employee, 'ABC' client, 11585.58 sales, "online" sale_type UNION ALL
SELECT 'Mary' as employee, 'XYZ' client, 4578.52 sales, "phone" sale_type UNION ALL
SELECT 'Mary' as employee, 'XYZ' client, 56853.45 sales, "online" sale_type
)
SELECT employee, AVG(sales) AS avg_sales
FROM sales_log
GROUP BY employee
我可以很容易地得到员工销售额的平均值。
是否有一种简单的方法也可以在一行中获得每种销售类型的平均值?这样输出就像:
employee
avg_sales
avg_phone_sales
avg_online_sales
John
20411.4825
3456.56
37366.405
Mary
18368.5325
2517.55
34219.515
提前谢谢你。
夫妇接近:
- DEMO 在底部:
- 如果类型有限,您可以为每一列使用 case 表达式。
- 如果它们是“动态”的,那么您需要一个动态枢轴。 (存在几个在线示例;但这意味着动态 SQL 容易被 SQL 注入)
- 注意:通常这样的数据格式化是在 UI 而不是 SQL.
中完成的
- 注意:使用 Null 可确保“空白”值不会影响您的平均值。
.
WITH sales_log AS
(
SELECT 'John' as employee, 'ABC' client, 1234.56 sales, 'phone' sale_type UNION ALL
SELECT 'John' as employee, 'ABC' client, 9857.56 sales, 'online' sale_type UNION ALL
SELECT 'John' as employee, 'XYZ' client, 5678.56 sales, 'phone' sale_type UNION ALL
SELECT 'John' as employee, 'XYZ' client, 64875.25 sales, 'online' sale_type UNION ALL
SELECT 'Mary' as employee, 'ABC' client, 456.58 sales, 'phone' sale_type UNION ALL
SELECT 'Mary' as employee, 'ABC' client, 11585.58 sales, 'online' sale_type UNION ALL
SELECT 'Mary' as employee, 'XYZ' client, 4578.52 sales, 'phone' sale_type UNION ALL
SELECT 'Mary' as employee, 'XYZ' client, 56853.45 sales, 'online' sale_type
)
SELECT employee, AVG(sales) AS avg_sales,
AVG(case when sale_type = 'phone' then sales else NULL end) as AVG_PhoneSales,
AVG(case when sale_type = 'online' then sales else NULL end) as AVG_OnLineSales
FROM sales_log
GROUP BY employee
给我们:
+----------+--------------------+-----------------------+--------------------+
| employee | avg_sales | AVG_phonesales | AVG_onlinesales |
+----------+--------------------+-----------------------+--------------------+
| Mary | 18368.532500000000 | 2517.5500000000000000 | 34219.515000000000 |
| John | 20411.482500000000 | 3456.5600000000000000 | 37366.405000000000 |
+----------+--------------------+-----------------------+--------------------+
DEMO :虽然不是 google big-query 语法在这个用例中是相同的。动态 SQL 或动态枢轴会有所不同。
动态示例:
考虑以下方法
select * from (
select employee, sale_type, avg(sales) as avg_sales
from sales_log
group by rollup (employee, sale_type)
having not employee is null
)
pivot (min(avg_sales) avg for ifnull(sale_type || '_sales', 'sales') in ('sales', 'phone_sales', 'online_sales'))
如果应用于我们问题中的样本数据 - 输出是
假设我在 BigQuery 中有以下简化数据:
WITH sales_log AS
(
SELECT 'John' as employee, 'ABC' client, 1234.56 sales, "phone" sale_type UNION ALL
SELECT 'John' as employee, 'ABC' client, 9857.56 sales, "online" sale_type UNION ALL
SELECT 'John' as employee, 'XYZ' client, 5678.56 sales, "phone" sale_type UNION ALL
SELECT 'John' as employee, 'XYZ' client, 64875.25 sales, "online" sale_type UNION ALL
SELECT 'Mary' as employee, 'ABC' client, 456.58 sales, "phone" sale_type UNION ALL
SELECT 'Mary' as employee, 'ABC' client, 11585.58 sales, "online" sale_type UNION ALL
SELECT 'Mary' as employee, 'XYZ' client, 4578.52 sales, "phone" sale_type UNION ALL
SELECT 'Mary' as employee, 'XYZ' client, 56853.45 sales, "online" sale_type
)
SELECT employee, AVG(sales) AS avg_sales
FROM sales_log
GROUP BY employee
我可以很容易地得到员工销售额的平均值。
是否有一种简单的方法也可以在一行中获得每种销售类型的平均值?这样输出就像:
employee | avg_sales | avg_phone_sales | avg_online_sales |
---|---|---|---|
John | 20411.4825 | 3456.56 | 37366.405 |
Mary | 18368.5325 | 2517.55 | 34219.515 |
提前谢谢你。
夫妇接近:
- DEMO 在底部:
- 如果类型有限,您可以为每一列使用 case 表达式。
- 如果它们是“动态”的,那么您需要一个动态枢轴。 (存在几个在线示例;但这意味着动态 SQL 容易被 SQL 注入)
- 注意:通常这样的数据格式化是在 UI 而不是 SQL. 中完成的
- 注意:使用 Null 可确保“空白”值不会影响您的平均值。
.
WITH sales_log AS
(
SELECT 'John' as employee, 'ABC' client, 1234.56 sales, 'phone' sale_type UNION ALL
SELECT 'John' as employee, 'ABC' client, 9857.56 sales, 'online' sale_type UNION ALL
SELECT 'John' as employee, 'XYZ' client, 5678.56 sales, 'phone' sale_type UNION ALL
SELECT 'John' as employee, 'XYZ' client, 64875.25 sales, 'online' sale_type UNION ALL
SELECT 'Mary' as employee, 'ABC' client, 456.58 sales, 'phone' sale_type UNION ALL
SELECT 'Mary' as employee, 'ABC' client, 11585.58 sales, 'online' sale_type UNION ALL
SELECT 'Mary' as employee, 'XYZ' client, 4578.52 sales, 'phone' sale_type UNION ALL
SELECT 'Mary' as employee, 'XYZ' client, 56853.45 sales, 'online' sale_type
)
SELECT employee, AVG(sales) AS avg_sales,
AVG(case when sale_type = 'phone' then sales else NULL end) as AVG_PhoneSales,
AVG(case when sale_type = 'online' then sales else NULL end) as AVG_OnLineSales
FROM sales_log
GROUP BY employee
给我们:
+----------+--------------------+-----------------------+--------------------+
| employee | avg_sales | AVG_phonesales | AVG_onlinesales |
+----------+--------------------+-----------------------+--------------------+
| Mary | 18368.532500000000 | 2517.5500000000000000 | 34219.515000000000 |
| John | 20411.482500000000 | 3456.5600000000000000 | 37366.405000000000 |
+----------+--------------------+-----------------------+--------------------+
DEMO :虽然不是 google big-query 语法在这个用例中是相同的。动态 SQL 或动态枢轴会有所不同。
动态示例:
考虑以下方法
select * from (
select employee, sale_type, avg(sales) as avg_sales
from sales_log
group by rollup (employee, sale_type)
having not employee is null
)
pivot (min(avg_sales) avg for ifnull(sale_type || '_sales', 'sales') in ('sales', 'phone_sales', 'online_sales'))
如果应用于我们问题中的样本数据 - 输出是