Я немного заржавел с моим SQL и столкнулся с небольшой проблемой с запросом.В нашем приложении у нас есть две относительные таблицы для этой проблемы.Есть записи, и для каждой записи есть N шагов.
Мы пытаемся оптимизировать наши запросы, поэтому вместо того, чтобы постоянно запрашивать все записи, мы просто запрашиваем записи, которые были обновлены после последней проверки.Шагов может быть много, поэтому этот запрос должен просто возвращать записи и некоторые сводные данные о шагах, и мы можем отдельно запросить шаги при необходимости.
Время начала записи и время обновления рассчитываются из первого и самого последнего времени шага процесса соответственно.Мы также должны сгруппировать статусы записей.
Вот запрос, который мы собираем в python, так как его легче читать:
statement = 'SELECT e.serial_number, ' + \
'e.description, ' + \
'min(p.start_time) begin_time, ' + \
'group_concat(p.status) status, ' + \
'max(p.last_updated) last_updated, ' + \
'FROM entries e ' + \
'LEFT OUTER JOIN process_steps p ON e.serial_number = p.serial_number ' + \
# if the user provides a "since" date, only return entries updated after
# that date
if since is not None:
statement += ' WHERE last_updated > "{0}"'.format(since)
statement += ' GROUP BY e.serial_number'
Проблема в том, что если мыпримените это WHERE
предложение, оно также фильтрует шаги процесса.Так, например, если у нас есть такая ситуация с двумя записями:
Entry: 123 foo
Steps:
1. start time 10:00, updated 10:30, status completed
2. start time 11:00, updated 11:30, status completed
3. start time 12:00, updated 12:30, status failed
4. start time 13:00, updated 13:30, status in_progress
Entry: 321 bar
Steps:
1. start time 01:00, updated 01:30, status completed
2. start time 02:00, updated 02:30, status completed
Если мы запросим без где, мы получим все записи.Таким образом, для этого случая он вернул бы:
321, bar, 01:00, "completed,completed", 02:30
123, foo, 10:00, "completed,completed,failed,in_progress", 13:30
Если бы у меня было время 12:15, то он вернул бы только это:
123, foo, 12:00, "failed,in_progress", 13:30
В этом результате время начала наступаетиз шага 3, а статусы только из шагов 3 и 4. Я ищу целую запись:
123, foo, 10:00, "completed,completed,failed,in_progress", 13:30
Итак, я хочу отфильтровать окончательные результаты на основе этого last_updated
value, но в настоящее время он также фильтрует результаты объединения, в результате чего значения begin_time
, last_updated
и status
отбрасываются, поскольку они рассчитываются с частичным набором шагов.Любые идеи, как изменить запрос, чтобы получить то, что я хочу здесь?
Редактировать:
Кажется, здесь также могут быть некоторые проблемы с именами.Имена, которые я использовал в примере кода, равны или похожи на то, что мы на самом деле имеем в нашем коде.Если мы изменим max(p.last_updated) last_updated
на max(p.last_updated) max_last_updated
и изменим предложение WHERE
на использование max_last_updated
, мы получим OperationalError: misuse of aggregate: max()
Мы также попытались добавить туда операторы AS
без разницы.