РАЗДЕЛЕНИЕ при первом использовании определенного продукта - PullRequest
0 голосов
/ 23 января 2020

Я пытаюсь создать таблицу, в которой указаны месяц, учетная запись и название продукта из нашей платежной базы данных. Однако я также хочу понять (для последующего когортного анализа), что самое раннее использование «Продукта А» также для каждой позиции. Я надеялся, что смогу сделать следующее:

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

... но кажется, что простое использование «продукта A» в предложении OVER не дает желаемого эффекта (кажется, просто возвращает первый месяц для AccountID).

Несмотря на то, что синтаксис в порядке и запрос выполняется, я, очевидно, что-то упускаю из-за PARTITION в предложении OVER. Любая помощь высоко ценится!

Ответы [ 2 ]

1 голос
/ 23 января 2020

Я думаю, вы хотите условное агрегирование вместе с оконной функцией:

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.

0 голосов
/ 23 января 2020

вы используете константу в разделе, это не повлияет на ваш результат, следует использовать столбец ProductName в разделе, чтобы получить самое раннее использование продукта

SELECT 
  Month,
  AccountID,
  ProductName,
  SUM(NetRevenue) AS NetRevenue,
  MIN(Month) OVER(PARTITION BY AccountID, ProductName) 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

...