2014-12-02 3 views
0

Сегодня мой вопрос связан с обозначением непрерывных периодов времени, когда выполняются заданные критерии. Мои сырые данные, представляющие интерес, выглядят так.Идентифицировать непрерывные периоды времени

Salesman ID  Pay Period ID   Total Commissionable Sales (US dollars) 
1     101      525 
1     102      473 
1     103      672 
1     104      766 
2     101      630 
2     101      625 
..... 

Я хочу отметить непрерывные периоды времени, когда продавец достиг 500 долларов продаж или больше. Мой идеальный результат должен выглядеть так.

[Salesman ID] [Start time]  [End time] [# Periods] [Average Sales] 
     1    101    101   1    525 
     1    103    107   5    621 
     2    101    103   3    635 
     3    104    106   3    538  

Я знаю, как все остальное, но я не могу понять, что не очень дорогой способ определить даты начала и окончания. Помогите!

+0

К сожалению, я считаю, что это сложная проблема в SQL. Вы можете сделать «итеративное» решение, используя рекурсивный CTE. Если проблема заключалась в том, чтобы разбить строки на группы * точно * 500, то вы могли бы сделать это с помощью функций окна. –

+0

Да .. Большинство решений, о которых я могу думать, занимает много итераций. Может быть, просто скопируйте это в Excel и напишите итеративный макрос в мышцу через него. –

+0

Вы заботитесь только о первых 500 долларов или приращениях в 500 долларов? Если первое, то есть решение. Проблема заключается в приращениях в 500 долларов. –

ответ

0

Попробуйте что-нибудь подобное. Самый внутренний select-statement в основном добавляет новый столбец в исходную таблицу с флагом, определяющим, когда начинается новая группа. Вне этого оператора мы используем этот флаг в общей сумме, которая затем перечисляет группы - мы вызываем этот столбец [ID группы]. Все, что осталось, затем отфильтровывать строки, где [Sales] < 500, и группа [Идентификатор продавца] и [Идентификатор группы].

SELECT [Salesman ID], MIN([Pay Period ID]) AS [Start time], 
    MAX([Pay Period ID]) AS [End time], COUNT(*) AS [# of periods], 
    AVG([Sales]) AS [Average Sales] 
FROM (
    SELECT [Salesman ID], [Pay Period ID], [Sales], 
     SUM(NewGroup) OVER (PARTITION BY [Salesman ID] ORDER BY [Pay Period ID] 
          ROWS UNBOUNDED PRECEDING) AS [Group ID] 
    FROM (
     SELECT T1.*, 
      CASE WHEN T1.[Sales] >= 500 AND (Prev.[Sales] < 500 OR Prev.[Sales] IS NULL) 
       THEN 1 ELSE 0 END AS [NewGroup] 
     FROM MyTable T1 
     LEFT JOIN MyTable Prev ON Prev.[Salesman ID] = T1.[Salesman ID] 
           AND Prev.[Pay Period ID] = T1.[Pay Period ID] - 1 
    ) AS InnerQ 
) AS MiddleQ 
WHERE [Sales] >= 500 
GROUP BY [Salesman ID], [Group ID] 
Смежные вопросы