На заводе в нашей компании есть физический процесс, который имеет двухэтапный запуск и двухэтапный процесс. Когда виджет начинает входить в процесс, создается новая запись, содержащая идентификатор виджета и метку времени (DateTimeCreated), и как только виджет полностью входит в процесс, другая метка времени регистрируется в другом поле для той же записи (DateTimeUpdated). Интервал составляет считанные минуты.
Точно так же, когда виджет начинает выходить из процесса, создается другая запись, содержащая идентификатор виджета и DateTimeCreated, причем DateTimeUpdated заполняется, когда виджет полностью выходит из процесса. В текущем дизайне таблицы «выходящая» запись неотличима от «входящей» записи (хотя данный идентификатор виджета встречается только один или два раза, поэтому представление может использовать этот факт для проведения различия, но давайте пока проигнорируем это).
Общее время работы виджета составляет несколько дней, но это не имеет большого значения для обсуждения. Что важно , так это то, что интервал при выходе из процесса всегда больше, чем при входе. Таким образом, очень упрощенный, воображаемый набор отсортированных значений интервала может выглядеть следующим образом:
1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 6, 7, 7, 7, 7, 8, 8, 8, 8, 10, 10, 10
Вы можете видеть, что есть пик в интервалах вокруг 3-минутной отметки («вход») и другой пик вокруг 7/8-минутной отметки («выход»). Я также исключил интервалы в 5 минут, чтобы продемонстрировать, что интервалы входа и выхода могут считаться взаимоисключающими.
Мы хотим ежедневно отслеживать производительность каждого этапа процесса, используя запрос для определения локальных средних значений кластеров точек входа и выхода. Таким образом, концептуально два набора данных могут быть разделены по обе стороны от общего среднего (в данном случае 5,375), а затем среднее значение рассчитывается для значений ниже разделения (2,75) и другого среднего значения выше разделения (8). Используя данные выше (в случайном порядке), средние значения отображаются в виде пунктирных линий на диаграмме ниже.
Мой текущий подход заключается в использовании двух общих табличных выражений, за которыми следует заключительный запрос объединения трех таблиц. Кажется, все в порядке, но я не могу не чувствовать, что это может быть лучше. Кто-нибудь хотел бы предложить альтернативный подход или другие наблюдения?
WITH cte_Raw AS
(
SELECT
DATEDIFF(minute, DateTimeCreated, DateTimeUpdated) AS [Interval]
FROM
MyTable
WHERE
DateTimeCreated > CAST(CAST(GETDATE() AS date) AS datetime) -- Today
)
, cte_Midpoint AS
(
SELECT
AVG(Interval) AS Interval
FROM
cte_Raw
)
SELECT
AVG([Entry].Interval) AS AverageEntryInterval
, AVG([Exit].Interval) AS AverageExitInterval
FROM
cte_Raw AS [Entry]
INNER JOIN
cte_Midpoint
ON
[Entry].Interval < cte_Midpoint.Interval
INNER JOIN
cte_Raw AS [Exit]
ON
[Exit].Interval > cte_Midpoint.Interval