首页 > 解决方案 > 通过第一次使用特定产品进行分区

问题描述

我正在尝试生成一个表格,其中列出了我们计费数据库中的月份、帐户和产品名称。但是,我也想了解(用于后续同期群分析)每个订单项的“产品 A”最早的用途是什么。我希望我能做到以下几点:

SELECT 
  Month,
  AccountID,
  ProductName,
  SUM(NetRevenue) AS NetRevenue,
  MIN(Month) OVER(PARTITION BY AccountID, 'Product A') AS EarliestUse 
FROM
  <<my-billing-table>>
WHERE
  NetRevenue > 0
  AND AccountID IN (
      SELECT DISTINCT AccountID
      FROM <<my-billing-table>>
      WHERE ProductName = 'Product A' AND NetRevenue > 0
    )
GROUP BY 1,2,3

...但似乎仅在OVER子句中使用“产品 A”并没有达到预期的效果(它似乎只返回 AccountID 的第一个月)。

虽然语法很好并且查询可以运行,但我显然遗漏了一些关于PARTITIONingOVER子句的内容。非常感谢任何帮助!

标签: sqlgoogle-bigquerypartitioning

解决方案


我认为您需要条件聚合和窗口函数:

SELECT Month, AccountID, ProductName,
       SUM(NetRevenue) AS NetRevenue,
       MIN(MIN(CASE WHEN ProductName = 'Product A' THEN month END)) OVER (PARTITION BY AccountID) AS EarliestUse 
FROM <<my-billing-table>>
WHERE NetRevenue > 0 AND
      AccountID IN (SELECT AccountID
                    FROM <<my-billing-table>>
                    WHERE ProductName = 'Product A' AND NetRevenue > 0
                   )
GROUP BY 1,2,3;

这里的关键表达式是嵌套在窗口函数中的聚合函数。聚合函数为MIN(CASE WHEN ProductName = 'Product A' THEN month END)。这会计算每行中指定产品的最早月份。这可能是结果集中的一列,您会在产品行上看到最小值。

然后,窗口函数将此值“传播”到给定的所有行上AccountID


推荐阅读