У меня есть модель, где Subjects
может вызывать определенные Events
.Событие имеет Date
и EventLevel
, и мне нужно создать запрос, в котором у меня есть обзор всего количества Subject
состояний за определенный период.Этот период может быть минутой или годом.В конце мне нужен отчет, который выглядит следующим образом:
1 jan 12:00: [{eventLevel: 3, count: 2}, {eventLevel: 2, count: 5}]
1 jan 13:00: [{eventLevel: 3, count: 3}, {eventLevel: 2, count: 4}]
Таким образом, за усеченный период (в нашем случае это час) существует число Subject
состояний на EventLevel
Я написал такой запрос в базе данных Postgres, используя Hibernate (но с собственным запросом).К сожалению, он в основном не показывает мне, что мне нужно.
StringBuilder whereClause = new StringBuilder();
whereClause.append(" WHERE subject.project_id = :projectId");
whereClause.append(" AND e.date >= :fromDate");
whereClause.append(" AND e.date < :toDate");
if (!skipEventConfigurations)
whereClause.append(" AND event_configuration.id in :eventConfigurationIds");
if (!skipSubjects)
whereClause.append(" AND subject.id in :subjectIds");
if (!skipMetrics)
whereClause.append(" AND metric.id in :metricIds");
if (!skipEventLevels)
whereClause.append(" AND e.event_level in :eventLevels");
String innersubquery = "SELECT" + " e.subject_id" + ",MAX(e.event_level) as maxeventlevel"
+ ",date_trunc(:period, e.date AT TIME ZONE :timezoneId) as fromdate FROM event e"
+ " INNER JOIN subject ON subject.id = e.subject_id"
+ " INNER JOIN metric ON metric.id = e.metric_id"
+ " INNER JOIN event_configuration_version ON event_configuration_version.id = e.event_configuration_version_id"
+ " INNER JOIN event_configuration ON event_configuration.id = event_configuration_version.event_configuration_id"
+ whereClause.toString() + " GROUP BY e.subject_id, fromdate";
String outersubquery = "SELECT" + " sub1.fromdate as fromdate"
+ ",sub1.maxeventlevel as eventlevel" + ",count(*) as count" + " FROM"
+ " (" + innersubquery + ") AS sub1"
+ " GROUP BY sub1.fromdate, sub1.maxeventlevel";
String queryString = "SELECT sub2.fromdate, sub2.eventlevel, sub2.count FROM ("
+ outersubquery + ") AS sub2"
+ " ORDER BY sub2.fromdate, sub2.eventlevel DESC";
Чтобы прояснить, что мне нужно, если, например, состояние Subject
было на EventLevel
3 в период 13:С 00 до 14:00, мне все еще нужно, чтобы это состояние отображалось в период с 14:00 до 15:00 (если, конечно, не появятся новые события, которые меняют этот факт)
Однако, когда еще не былолюбое событие в определенный усеченный период (скажем, между 14:00 и 15:00), тогда не будет никаких результатов для этого.Это имеет смысл с этим запросом, но я не знаю, как его решить.Также приветствуются альтернативные решения, в том числе вывод, что это просто не возможно.
Обратите внимание, что, поскольку в запросе используются внешние ключи, и мы в идеале сохраняем эту функциональность реляционной базы данных, было бы идеально, если бы мыможет придерживаться этого, а не, например, нуждаться в более конкретной базе данных временных рядов.