четверг, 29 июля 2010 г.

sql затуп

Дальше интересно только гражданам, хорошо знающим sql вобще и mysql в частности

А вот например есть у меня две таблицы, описывающие некий процесс и список ошибок при его исполнении - что-нибудь в таком духе:

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;


И второй вопрос - в сто раз мозголомнее первого - а что если я хочу найти не просто процессы где случились все ошибки err1...errN, но те из них, где они случились именно в такой последовательности - сначала err1, потом err2, потом ... и наконец errN ? Мне в голову не пришло ничего лучше чем для каждого процесса грузить список его ошибок, отсортированный по date, и искать по нему уже на более нормальном языке чем sql. Скорее всего я опять же не прав и в упор не вижу какого-нибудь обидно простого и очевидного решения

Комментариев нет:

Отправить комментарий