2013-12-10 2 views
1

У меня есть таблица 'Course' и таблица 'Event'. Я бы хотел, чтобы все курсы действительно имели место, т. Е. Они не отменены событием.Смуты, осмысляющие запрос

Я сделал это простым запросом на весь курс и анализ сценариев (в основном, некоторые петли), но этот запрос занимает время, которое я считаю слишком долго. Я думаю, что то, что я хочу, возможно в одном запросе и без циклов для оптимизации этого запроса.

Вот подробности:

  • 'Course' c имеют поля 'date', 'duration' и многие ко многим отношения с 'Grade' столом
  • 'Event' e имеют поля 'begin', 'end', 'break' и многие ко многим отношения с таблицей 'Grade'
  • Курс отменяется событием, если оно происходит одновременно, и если событие является перерывом ())
  • Курс отменяется событием, если все оценки курса происходят в событиях, происходящих одновременно (возможно много событий, я должен подвести итоги этих событий и сравнить их с классы курсов). Это та часть, которую я делаю с циклом, у меня есть некоторые проблемы, чтобы концептуализировать это.

Любая помощь приветствуется,

Спасибо заранее,

PS: Я использую MySQL

EDIT: детали Таблицы

-Course

+-----------+-------------+------+-----+---------+----------------+ 
| Field  | Type  | Null | Key | Default | Extra   | 
+-----------+-------------+------+-----+---------+----------------+ 
| id  | int(11)  | NO | PRI | NULL | auto_increment | 
| date  | datetime | NO |  | NULL |    | 
| duration | time  | NO |  | NULL |    | 
| type  | int(11)  | NO |  | NULL |    | 
+-----------+-------------+------+-----+---------+----------------+ 

+-------+---------------------+----------+------+ 
| id | date    | duration | type | 
+-------+---------------------+----------+------+ 
| 1 | 2013-12-10 10:00:00 | 02:00:00 | 0 | 
| 2 | 2013-12-11 10:00:00 | 02:00:00 | 0 | 
+-------+---------------------+----------+------+ 

-Event

+-------------+-------------+------+-----+---------+----------------+ 
| Field  | Type  | Null | Key | Default | Extra   | 
+-------------+-------------+------+-----+---------+----------------+ 
| id   | int(11)  | NO | PRI | NULL | auto_increment | 
| begin  | datetime | NO |  | NULL |    | 
| end   | datetime | YES |  | NULL |    | 
| break  | tinyint(1) | NO |  | NULL |    | 
+-------------+-------------+------+-----+---------+----------------+ 

+----+---------------------+---------------------+-------+ 
| id | begin    | end     | break | 
+----+---------------------+---------------------+-------+ 
| 1 | 2013-12-10 00:00:00 | 2013-12-11 23:59:00 |  1 | 
+----+---------------------+---------------------+-------+ 

-course_grade

+-----------+----------+ 
| course_id | grade_id | 
+-----------+----------+ 
|  1  |  66 | 
|  2  |  65 | 
|  2  |  66 | 
+-----------+----------+ 

-event_grade

+----------+----------+ 
| grade_id | event_id | 
+----------+----------+ 
|  66 |  1 | 
+----------+----------+ 

Так вот, только должен появиться курс 2, потому что курс 1 имеет только один класс, и этот класс имеет событие.

+3

Вы можете оставить SQLFiddle пожалуйста? Я пытаюсь визуализировать вашу схему и не удается ... –

+0

, пожалуйста, ставьте таблицы samples.bye – Pericles

+0

SQL Fiddle - это опция, но также показывающая данные образца даже здесь, просто не используйте вкладки для форматирования и выделения и Ctrl + K для форматирования текст (или с изображением фигурного скобки). Это звучит как школьные курсы с оценками, но событие, имеющее оценки, не имеет смысла, если в курсе ex: 1 не много событий (тестовый, среднесрочный, окончательный экзамен), а все события и оценки прерываются ... Если бы это было так, я бы ожидал таблицу STUDENT/GRADEs. – DRapp

ответ

0
  1. Я люблю загадки, это хороший один, имеет много решений, я думаю, что
  2. Как вы говорите «Любая помощь приветствуется», я даю ответ Altough его не решение (и это делает не вписывается в комментарий)
  3. Я не знаю, если вы просто хотите (A) голые высказывания (вверх и вниз), или если вы хотите (B) понять, как добраться до решения, я беру (B)

Я начинаю с «что бы изменить», прежде чем начинать с решения:

вы смешиваете date, datetime, start, end и duration, попробуйте использовать только один логики (если это ваша модель конечно), то есть.

событие/курс имеет начало и конец времени (или начать/продолжительность)

продолжительность должна (имхо) не будет время

попытаться найти наименьший квант времени для событий/курса (в есть 1 сек. событий или является зернистостью 5 '(т. е. 10:00, 10:05, 10:10 и т. д.) действительный компромисс?

Мое решение, prgmatic, не академическое (звучит смешно , но работает хорошо в simillar prob, я видел аннотацию)

Создать таблицу (T_TIME_OF_DAY), имеющее все от 00:00, 00:05, .. 23:55

Создать таблицу (T_DAYS) в действительном и ПОЛЕЗНОМ диапазоне (год?)

в carthesian продукт - назовите его точками во времени - (т.е. select date, time from T_DAYS,T_TIME_OF_DAY no condition) из них (дней x раз) 300 * 24 * 12 ~ 100.000 строк, если вам нужно посмотреть целый год (и 5 'в порядке для вас) - это не так много и нет проблем

следующий шаг состоит в том, чтобы присоединиться к проклятиям, соответствующим вашим точкам во времени (и строки до < < 100.000)

Если вы соедините их с вашими событиями (снова используя момент времени), вы должны получить то, что хотите.

simplyfied quarters of a day: 

       12 12 12 12 12 12 12 12 
       08 09 10 11 12 13 14 15 
       |...|...|...|...|...|...|...|... 
    grade 65 (C).............2.................. 
    grade 66 (C).........1...2.................. 
    grade 65 (E)................................ 
    grade 66 (e)........1111.................. 

(аннотация: Я использую эту логику для расчета availabillity услуг относительно их простоев в месяц/год, и могу использовать уже временные срезы, полученные данные для отображения)

+0

Привет, спасибо за ваш ответ. Все ответы хороши для чтения;) В течение времени/даты и времени, после попыток отдельных попыток, мне удобнее иметь продолжительность как время. Мне нужно только неделю или месяц, а не целый год. На самом деле вы показываете способ найти пересечения между курсами и событиями? Моя проблема больше связана с поиском общих оценок между курсом и событием, чтобы узнать, отменено ли оно или нет. Но спасибо за этот метод, я никогда не видел этого, и я потрачу время на его анализ. Звучит интересно. –

+0

вам нужны перекрестки между этими двумя таблицами, чтобы найти оценки, не так ли? – halfbit

+0

Да, конечно, но в настоящее время я использую что-то вроде '(ADDTIME (c.date, c.duration) <= e.begin ИЛИ c.date> = e.end) ИЛИ условия ...' и он работает хорошо. Там, где я действительно застрял, это для всех классов. –

0

(второго ответа, потому что это суммарно отличается и mor3 стандарт Подход)

Я сделал SQLFiddle для вас

так, что делать:

и то будет решение:

шага один (в виде) выбрать курс, классы (назовет их C)

шаг два (в виде) выберите события, оценки (позволяет называть их E)

и - тада -

выбрать все из C, где там нет строки в E, которые имеют один и тот же класс и ту же дату (как-то) и типСобытия = «перерыв»

поэтому ваше решение:

select 
    id, date start_time, date+duration end_time, grade_id 
    from Course c join course_grade cg on c.id=cg.course_id 
    where not exists ( 
    select grade_id, begin start_time, end end_time 
    from event_grade eg join event e on eg.event_id=e.id 
    where 
     eg.grade_id=cg.grade_id 
     and e.break=1 
     and 
     (
     (e.begin<=c.date and e.end >=c.date+c.duration) 
     or e.begin between c.date and c.date+c.duration 
     or e.end between c.date and c.date+c.duration 
     )  

    ) 

я не принимать никакого внимания оптимизации здесь

Смежные вопросы