У меня есть журнал клиентов, проходящих рабочий процесс.Я хочу сделать две вещи, и я борюсь с любой из них.
Первое: я хочу отфильтровать клиентов, которые не начали, войдя в первое состояние в начале рабочего процесса (введите состояние0).
Второе: для остальных клиентов я хочу знать, сколько времени они потратили на каждом шаге рабочего процесса.
Каждая запись имеет:
- CUSTOMER_ID (целое число)
- STATE (целое число)
- ACTION (вход или выход из этого состояния, varchar)
- UPDATE_DT (отметка времени входа)
Я попытался сделать запрос, который позволил бы мне получить временную метку входа и выхода, сгруппированную по клиенту и состоянию:
SELECT
CUSTOMER_ID,
STATE,
MIN(UPDATE_DT) AS ENTRY_DATE,
MAX(UPDATE_DT) AS EXIT_DATE
FROM LOG_DATA
GROUP BY CUSTOMER_ID, STATE
ORDER BY CUSTOMER_ID, STATE;
Но я сразу столкнулся с несколькими проблемами.Запрос будет работать нормально, но:
- Я не удалил клиентов, которые не начали с входа в состояние 0
- Не все клиенты гарантированно имеют обе записии дату выхода для каждого состояния, поэтому иногда мой МИН / МАКС не работает
Я попытался сосредоточиться на первой проблеме, добавив дополнительный атрибут в свой выбор таким образом:
MIN(STATE) OVER(PARTITION BY CUSTOMER_ID) AS EARLIEST_STATE
Но потом столкнулся с несколькими проблемами.Я не могу включить EARLIEST_STATE в качестве условия WHERE или GROUP BY HAVING, потому что для WHERE его не существует, и GROUP BY не позволит мне включить EARLIEST_STATE.
, как я и думал через этостановится еще хуже - MIN (STATE) может доказать, в лучшем случае, что клиент имеет STATE = 0, но не то, что у него есть запись, которая говорит, что ACTION = "enter" и STATE = 0. Таким образом, этот подход терпит неудачу не только потому, что я не могу получитьон запускается, но потому что это также логически не правильно.
Я знаю, что мог бы сделать несколько SELECT с SELECT, но это кажется неуклюжим, и я хочу узнать, как это сделать правильно.Также не помогает то, что я имею дело с 10 миллионами строк данных, поэтому важна эффективность.
Я использую Postgres 9.5, я не контролирую ни технологию БД, ни схему данных в этомэкземпляр.
Это было бы медленно, но я мог бы использовать что-то на своем Python для этого, но мне бы очень хотелось узнать правильный способ сделать это с помощью БД.