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 语句中被调用时不再是聚合,它在子查询的结果中。

  1. 有子句

如果子查询不是您的菜,您可以在 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),我很乐意为您的用例分享一个示例。

尽管如此,希望这对您有所帮助! 汤姆