2014-09-17 4 views
0

В моей базе данных есть четыре типа лиц, youngOrc, oldOrc, youngHuman, oldHuman.MySQL query inested where condition

Лицо принадлежит к типу, относящемуся к диапазону дат. Таким образом, у меня есть таблицы, как это для каждого типа:

 
youngOrcList 
------------------- 
individual_id, 
start_date, 
end_date 

Это означает, что парень с individual_id является youngOrc между дате начала и окончания. Он может быть чем-то другим вне этого диапазона. Аналогично, у меня есть таблица youngHuman.

Теперь, реальная таблица процентов, что я хочу, чтобы фильтровать это событие:

 
events 
------------------ 
source_individual_id 
target_individual_id 
event_date 

Таблица события записывает все события между двумя людьми, в моей области. Я хочу фильтровать, чтобы выбрать events между youngOrc и youngHuman.

Так что это «вложенное» состояние рода, где мне нужны и events.source_individual_id IN youngOrcList И events.event_date BETWEEN youngOrcList.start_date AND youngOrcList.end_date. Как это сделать?

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

+0

Что вы пытались до сих пор? Также это поможет, если вы предоставите образцы данных и ожидаемые результаты. – Bulat

+0

Похоже, у вас плохая схема. Для меня нет причин иметь 4 разделительных элемента для них для классов людей. Почему не только одна таблица со всеми людьми. Старый/молодой действительно просто свойство личности (и я предполагаю, что может измениться с течением времени - так что вы собираетесь перемещать людей из одной таблицы в другую, поскольку они стареют в вашей текущей схеме?). Также человеческий против орка можно рассматривать как свойство личности. Почему не просто люди и события, которые относятся к людям? –

+0

Юношеские объекты - это таблицы, которые я создаю для облегчения запроса. В реальной схеме есть таблица, которая отображает индивидов на их типы, зависящие от диапазона дат, как вы сказали. Будет ли использование этой таблицы проще для меня? – Heisenberg

ответ

0

Вы можете использовать присоединиться на столах. Они могут быть сдвинуты на поле individual_id так, то единственное условие осталось WHERE пункта будет состояние дата:

SELECT * 
FROM youngOrcList AS o 
JOIN events AS e ON e.source_individual_id = o.individual_id 
JOIN youngHumanList AS h ON h.individual_id = e.target_individual_id 
WHERE e.event_date BETWEEN o.start_date AND o.end_date 
AND e.event_date BETWEEN h.start_date AND h.end_date 

Альтернативно, условие WHERE может быть:

WHERE e.event_date > MAX(o.start_date, h.start_date) 
AND e.event_date < MIN(o.end_date, h.end_date) 
1

Это даст вам все события между youngOrc и youngHuman:

SELECT * 
FROM 
Events e 
WHERE EXISTS (
     SELECT * FROM youngHumanList 
     WHERE individual_id IN (e.source_individual_id, e.target_individual_id) 
      AND e.event_date BETWEEN start_date AND end_date) 
    AND EXISTS (
     SELECT * FROM youngOrcList 
     WHERE individual_id IN (e.source_individual_id, e.target_individual_id) 
      AND e.event_date BETWEEN start_date AND end_date) 
+0

Не могли бы вы объяснить, как эта работа? Во-первых, я думал, что за «IN» должен следовать подзапрос «SELECT». Я не ожидал 'IN (e.source_individual_id, e.target_individual_id)' работать (он делает). Во-вторых, 'e.event_date BETWEEN start_date AND end_date' - как я знаю, что это' event_date', связанный с 'individual_id', о котором идет речь? – Heisenberg

+1

Оператор 'IN' принимает список значений, а также подзапросы. Поэтому вы можете написать 'WHERE a IN (1, 2, 3)'. Что касается 'event_date', это всегда происходит из текущей записи в списке событий. Таким образом, оба условия имеют одинаковое значение e.event_date, но мы ищем существование Orc и Human отдельно, и только если оба существуют для события, мы возвращаем запись – Bulat

+0

Итак, хотя 'events' имеет миллионы строк, в каждом итерация, 'e.source_individual_id',' e.target_individual_id' и 'e.event_date' все смотрят на одну и ту же строку? – Heisenberg