AWS Timestream 查询以获取样本第一个月的平均测量值
AWS Timestream query to get average measure for the first month of samples
在 AWS Timestream 中,我试图获取第一个月的平均心率,因为我们收到了特定用户的心率样本和上周的平均值。我在获取第一个月部分的查询时遇到问题。当我尝试在 where 子句中使用 MIN(time)
时出现错误:WHERE 子句不能包含聚合、window 函数或分组操作.
SELECT * FROM "DATABASE"."TABLE"
WHERE measure_name = 'heart_rate' AND time < min(time) + 30
如果我将其添加为列并尝试对该列进行查询,我会收到错误消息:列 'first_sample_time' 不存在
SELECT MIN(time) AS first_sample_time FROM "DATABASE"."TABLE"
WHERE measure_name = 'heart_rate' AND time > first_sample_time
此外,如果我尝试添加到 MIN(time)
,我会收到错误消息:第 1:18 行:'+' 无法应用于时间戳,整数
SELECT MIN(time) + 30 AS first_sample_time FROM "DATABASE"."TABLE"
这是我最终想出的方法,但我想知道是否有更好的方法?
WITH first_month AS (
SELECT
Min(time) AS creation_date,
From_milliseconds(
To_milliseconds(
Min(time)
) + 2628000000
) AS end_of_first_month,
USER
FROM
"DATABASE"."TABLE"
WHERE
USER = 'xxx'
AND measure_name = 'heart_rate'
GROUP BY
USER
),
first_month_avg AS (
SELECT
Avg(hm.measure_value :: DOUBLE) AS first_month_average,
fm.USER
FROM
"DATABASE"."TABLE" hm
JOIN first_month fm ON hm.USER = fm.USER
WHERE
measure_name = 'heart_rate'
AND hm.time BETWEEN fm.creation_date
AND fm.end_of_first_month
GROUP BY
fm.USER
),
last_week_avg AS (
SELECT
Avg(measure_value :: DOUBLE) AS last_week_average,
USER
FROM
"DATABASE"."TABLE"
WHERE
measure_name = 'heart_rate'
AND time > ago(14d)
AND USER = 'xxx'
GROUP BY
USER
)
SELECT
lwa.last_week_average,
fma.first_month_average,
lwa.USER
FROM
first_month_avg fma
JOIN last_week_avg lwa ON fma.USER = lwa.USER
是否有更好或更有效的方法来做到这一点?
我可以看到您 运行 在解决问题的过程中遇到了一些挑战,希望我能为您解决这些问题,并提出一种更简洁的方法来实现您的解决方案。
聚合过滤
正如您亲身经历的那样,SQL 不允许在 where 语句中进行聚合,并且您也无法过滤在 [=42] 中创建的 new 列=] 语句,例如聚合或案例语句,因为那些 columns/results 不存在于您正在查询的 table 中。
幸运的是,有一些方法可以解决这个问题,例如:
将您的主查询设为子查询,然后过滤该查询的结果,如下所示
Select * from (select *,count(that_good_stuff) as total_good_stuff from tasty_table group by 1,2,3) where total_good_stuff > 69
这是可行的,因为聚合列 (count) 在 where 语句中被调用时不再是聚合,它在子查询的结果中。
- 有子句
如果子查询不是您的菜,您可以在 group by 语句之后直接使用 having 子句,除了专门用于处理聚合外,它的作用类似于 where 语句.
在大多数情况下,这比诉诸子查询要好,因为它更具可读性,而且我相信效率更高。
select *,count(that_good_stuff) as total_good_stuff from tasty_table group by 1,2,3 having total_good_stuff > 69
最后,window 语句非常棒...它们确实帮助我简化了过去提出的许多查询,不再需要 subqueries/ctes。如果您可以分享一些示例原始数据(当然删除任何 pii),我很乐意为您的用例分享一个示例。
尽管如此,希望这对您有所帮助!
汤姆
在 AWS Timestream 中,我试图获取第一个月的平均心率,因为我们收到了特定用户的心率样本和上周的平均值。我在获取第一个月部分的查询时遇到问题。当我尝试在 where 子句中使用 MIN(time)
时出现错误:WHERE 子句不能包含聚合、window 函数或分组操作.
SELECT * FROM "DATABASE"."TABLE"
WHERE measure_name = 'heart_rate' AND time < min(time) + 30
如果我将其添加为列并尝试对该列进行查询,我会收到错误消息:列 'first_sample_time' 不存在
SELECT MIN(time) AS first_sample_time FROM "DATABASE"."TABLE"
WHERE measure_name = 'heart_rate' AND time > first_sample_time
此外,如果我尝试添加到 MIN(time)
,我会收到错误消息:第 1:18 行:'+' 无法应用于时间戳,整数
SELECT MIN(time) + 30 AS first_sample_time FROM "DATABASE"."TABLE"
这是我最终想出的方法,但我想知道是否有更好的方法?
WITH first_month AS (
SELECT
Min(time) AS creation_date,
From_milliseconds(
To_milliseconds(
Min(time)
) + 2628000000
) AS end_of_first_month,
USER
FROM
"DATABASE"."TABLE"
WHERE
USER = 'xxx'
AND measure_name = 'heart_rate'
GROUP BY
USER
),
first_month_avg AS (
SELECT
Avg(hm.measure_value :: DOUBLE) AS first_month_average,
fm.USER
FROM
"DATABASE"."TABLE" hm
JOIN first_month fm ON hm.USER = fm.USER
WHERE
measure_name = 'heart_rate'
AND hm.time BETWEEN fm.creation_date
AND fm.end_of_first_month
GROUP BY
fm.USER
),
last_week_avg AS (
SELECT
Avg(measure_value :: DOUBLE) AS last_week_average,
USER
FROM
"DATABASE"."TABLE"
WHERE
measure_name = 'heart_rate'
AND time > ago(14d)
AND USER = 'xxx'
GROUP BY
USER
)
SELECT
lwa.last_week_average,
fma.first_month_average,
lwa.USER
FROM
first_month_avg fma
JOIN last_week_avg lwa ON fma.USER = lwa.USER
是否有更好或更有效的方法来做到这一点?
我可以看到您 运行 在解决问题的过程中遇到了一些挑战,希望我能为您解决这些问题,并提出一种更简洁的方法来实现您的解决方案。
聚合过滤 正如您亲身经历的那样,SQL 不允许在 where 语句中进行聚合,并且您也无法过滤在 [=42] 中创建的 new 列=] 语句,例如聚合或案例语句,因为那些 columns/results 不存在于您正在查询的 table 中。
幸运的是,有一些方法可以解决这个问题,例如:
将您的主查询设为子查询,然后过滤该查询的结果,如下所示
Select * from (select *,count(that_good_stuff) as total_good_stuff from tasty_table group by 1,2,3) where total_good_stuff > 69
这是可行的,因为聚合列 (count) 在 where 语句中被调用时不再是聚合,它在子查询的结果中。
- 有子句
如果子查询不是您的菜,您可以在 group by 语句之后直接使用 having 子句,除了专门用于处理聚合外,它的作用类似于 where 语句.
在大多数情况下,这比诉诸子查询要好,因为它更具可读性,而且我相信效率更高。
select *,count(that_good_stuff) as total_good_stuff from tasty_table group by 1,2,3 having total_good_stuff > 69
最后,window 语句非常棒...它们确实帮助我简化了过去提出的许多查询,不再需要 subqueries/ctes。如果您可以分享一些示例原始数据(当然删除任何 pii),我很乐意为您的用例分享一个示例。
尽管如此,希望这对您有所帮助! 汤姆