首页 > 解决方案 > 如何在 Snowflake SQL 中同时聚合并取一列的最后一个值?

问题描述

我需要聚合一些数据,同时获取其中一列的最后一个(按时间顺序排列的)值......

我可以用一个 CTE 来实现这一点,但想知道是否有更短/更有效的方法来做到这一点。

假设我卖杂货,并且在我的数据库中有“实际”销售额和“估计”销售额。

我想报告每种产品的总销售额,并返回最新的销售数字是 ACTUAL 还是 ESTIMATE。

这是我的 CTE 解决方案

CREATE OR REPLACE TABLE SALES_DATA (SOMETHING         STRING NOT NULL
                                  , DATA_QUALITY      STRING NOT NULL
                                  , SALES             INTEGER
                                  , CREATED_ON        TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP()
                                  );

INSERT INTO SALES_DATA(SOMETHING, DATA_QUALITY, SALES, CREATED_ON)
  VALUES('CARROTS', 'ESTIMATE',  23, '2021-03-09 13:09')
      , ('BANANAS', 'ACTUAL',     5, '2021-03-09 13:34')
      , ('CARROTS', 'ACTUAL',    12, '2021-03-09 14:09')
      , ('ORANGES', 'ACTUAL',    24, '2021-03-10 13:09')
      , ('BANANAS', 'ESTIMATE',  14, '2021-03-11 00:00')
  ;
  
-- At leaf level, just ensure all rows report the latest Data Quality instead of that of the row itself
WITH LATEST_DATA_QUALITY_ONLY
AS (
SELECT  SOMETHING
      , SALES
      , LAST_VALUE(DATA_QUALITY) OVER(PARTITION BY SOMETHING ORDER BY CREATED_ON) AS LATEST_DATA_QUALITY
  FROM SALES_DATA
)
SELECT SOMETHING
      ,MAX(LATEST_DATA_QUALITY) AS LATEST_DATA_QUALITY
      ,SUM(SALES) AS SALES
  FROM LATEST_DATA_QUALITY_ONLY 
  GROUP BY SOMETHING
  ORDER BY SOMETHING;

我期待这个结果

在此处输入图像描述

标签: sqlsnowflake-cloud-data-platform

解决方案


使用ARRAY_AGG创建按第一个元素排序CREATED_ON并访问第一个元素的数组:

SELECT SOMETHING
  ,(ARRAY_AGG(LATEST_DATA_QUALITY) WITHIN GROUP(ORDER BY CREATED_ON DESC))[0] 
    AS LATEST_DATA_QUALITY
  ,SUM(SALES) AS SALES   
FROM LATEST_DATA_QUALITY_ONLY    
GROUP BY SOMETHING   
ORDER BY SOMETHING;

此模式试图模仿KEEP子句。


推荐阅读