А вот например есть у меня две таблицы, описывающие некий процесс и список ошибок при его исполнении - что-нибудь в таком духе:
create table job_process (
ID integer not null AUTO_INCREMENT,
Start DATETIME,
End DATETIME,
PRIMARY KEY(ID)
);
create table job_errors (
ID integer not null AUTO_INCREMENT,
date DATETIME,
ErrNum Integer not null,
JobId integer not null,
PRIMARY KEY(ID),
FOREIGN KEY(JobId) REFERENCES job_process(ID) ON DELETE CASCADE
);
Ничего сложного пока - табличка job_process говорит, когда процесс начался и закончился, табличка job_errors содержит список ошибок - поле ErrNum содержит код ошибки, а JobId связывает ее с процессом, в котором ошибка случилась
И вот нужно мне извлечь список процессов, в которых за определенное время произошли все из ошибок err1 ... errN. Мое рабоче-крестьянское сознание живо набросало мне примерно следующую простынь для подобного запроса:
select ID from job_process where
exists (select * from job_errors where date between "start" and "stop" and ErrNum = err1 and JobId = job_process.ID) and
...
exists (select * from job_errors where date between "start" and "stop" and ErrNum = errN and JobId = job_process.ID)
Выглядит устрашающе - для каждой ошибки нужно городить новый подзапрос, где кроме ошибки указывать еще и время начала и окончания. Вопрос - можно как-нибудь упростить этого крокодила ? Я правильно понимаю что оно будет столько раз ездить по таблице job_errors, сколько ошибок я хочу найти ?
Update: мне тут подсказали как можно свернуть эту простынь:
select JobId from
( select distinct JobId, ErrNum from job_errors where date between "start" and "stop" and ErrNum in (err1, err2, ..., errN)) T
GROUP By (JobId) having COUNT(*) = N;
И второй вопрос -
Комментариев нет:
Отправить комментарий