如何在 SQL 中跨 objects/arrays 映射函数?
How to map functions across objects/arrays in SQL?
假设我在 table 中有一些数据,其中包含每天进入商店的顾客的姓名和年龄(id 用作唯一的日期标识符)。
id, obj
-----------------------------------------------------------------
1, [{'name': 'jenny', 'age':22}, {'name': 'adam', 'age':32},...]
2, [{'name': 'adam', 'age':32}, {'name': 'beth', 'age':27},...]
我想做的是找出每天的平均年龄
SELECT id, AVG([o['age'] for o in obj]) AS avg_age
FROM t
以及所需的输出
id, avg_age
--, -------
1, 27
2, 29.2
这显然行不通,因为 python-like 列表理解在 SQL 中行不通。在 SQL 中执行此操作的正确方法是什么?
假设您的数据实际上是 json 您可以对其进行操作:
-- sample data
WITH dataset (id, obj) AS (
VALUES ( 1, '[{"name": "jenny", "age":22}, {"name": "adam", "age":32}]'),
(2, '[{"name": "adam", "age":32}, {"name": "beth", "age":27}]')
)
--query
select id,
reduce(arr, 0, (s, x) -> s + x, s -> s) / cardinality(arr)
from
(
select id,
transform(
cast(json_parse(obj) as array(json)), -- parse json and cast to array of json
j->cast(json_extract_scalar(j, '$.age') as double) -- extract age
) arr
from dataset
)
输出:
id
_col1
1
27.0
2
29.5
对于较新的版本,您可以尝试替换外部 select 并减少为 array_average
:
select id,
array_average(transform(
cast(json_parse(obj) as array(json)),
j->cast(json_extract_scalar(j, '$.age') as double)
)) arr
from dataset
假设我在 table 中有一些数据,其中包含每天进入商店的顾客的姓名和年龄(id 用作唯一的日期标识符)。
id, obj
-----------------------------------------------------------------
1, [{'name': 'jenny', 'age':22}, {'name': 'adam', 'age':32},...]
2, [{'name': 'adam', 'age':32}, {'name': 'beth', 'age':27},...]
我想做的是找出每天的平均年龄
SELECT id, AVG([o['age'] for o in obj]) AS avg_age
FROM t
以及所需的输出
id, avg_age
--, -------
1, 27
2, 29.2
这显然行不通,因为 python-like 列表理解在 SQL 中行不通。在 SQL 中执行此操作的正确方法是什么?
假设您的数据实际上是 json 您可以对其进行操作:
-- sample data
WITH dataset (id, obj) AS (
VALUES ( 1, '[{"name": "jenny", "age":22}, {"name": "adam", "age":32}]'),
(2, '[{"name": "adam", "age":32}, {"name": "beth", "age":27}]')
)
--query
select id,
reduce(arr, 0, (s, x) -> s + x, s -> s) / cardinality(arr)
from
(
select id,
transform(
cast(json_parse(obj) as array(json)), -- parse json and cast to array of json
j->cast(json_extract_scalar(j, '$.age') as double) -- extract age
) arr
from dataset
)
输出:
id | _col1 |
---|---|
1 | 27.0 |
2 | 29.5 |
对于较新的版本,您可以尝试替换外部 select 并减少为 array_average
:
select id,
array_average(transform(
cast(json_parse(obj) as array(json)),
j->cast(json_extract_scalar(j, '$.age') as double)
)) arr
from dataset