2013-01-14 2 views
2

я вроде застрял ..MySQL JOIN/GROUP один-ко-многим

У меня есть две таблицы

mysql > EXPLAIN event; 
+-------------+--------------+------+-----+---------------------+-----------------------------+ 
| Field  | Type   | Null | Key | Default    | Extra      | 
+-------------+--------------+------+-----+---------------------+-----------------------------+ 
| id   | int(11)  | NO | PRI | NULL    | auto_increment    | 
| name  | varchar(100) | NO | MUL |      |        | 
| extUrl  | varchar(192) | NO |  |      |        | 
+-------------+--------------+------+-----+---------------------+-----------------------------+ 

Одно событие может иметь много

mysql> explain eventDate; 
+----------------+--------------+------+-----+---------------------+-----------------------------+ 
| Field   | Type   | Null | Key | Default    | Extra      | 
+----------------+--------------+------+-----+---------------------+-----------------------------+ 
| id    | int(11)  | NO | PRI | NULL    | auto_increment    | 
| category_id | int(11)  | NO | MUL | 0     |        | 
| event_id  | int(11)  | NO | MUL | 0     |        | 
| location_id | int(11)  | NO | MUL | 0     |        | 
| name   | varchar(100) | NO |  |      |        | 
| eventDate  | timestamp | NO |  | 0000-00-00 00:00:00 |        | 
+----------------+--------------+------+-----+---------------------+-----------------------------+ 

Я бы как запросить событие на id, с location_idследующий предстоящийeventDate и я застрял, как сформировать этот запрос

настоящее время у меня этот

SELECT 
     e.id, 
     d.location_id, 
     d.eventDate 
FROM 
     event e 
      INNER JOIN eventDate d ON d.event_id = e.id AND d.eventDate >= CURRENT_TIMESTAMP 
WHERE 
     e.id = 5107 
GROUP BY 
     e.id 
ORDER BY 
     d.eventDate ASC 

Теперь это возвращает результат, но GROUP BY событие, поэтому я не уверен, как убедиться, что на самом деле выбран следующий EVENTDATE. Кроме того, я не использовал какую-либо агрегированную функцию (группа по одному, совокупность многих), что, похоже, не является чистым и четко определенным требованием к результату - MySQL случайно выбирает одну из строк eventDate, не так ли?

+0

будет выбрать любого из eventdates больше или равно текущей временной отметке. Поскольку вы группируете его по ID, MySQL не имеет понятия, какая строка важнее для вас. Следовательно, он выберет либо первый, либо последний, с которым он сталкивается, а не - как я полагаю, вы хотите, чтобы это произошло - следующее восходящее событие Event. Вам нужно будет расширить предложение 'WHERE' и/или поместить в него' LIMIT', чтобы выбрать только 1 – Tikkes

+0

Да, я хочу иметь следующий предстоящий eventDate, я получаю одну строку результатов из-за комбинации ' WHERE e.id = 5107' и 'GROUP BY e.id', но я не уверен, что предложение' ORDER BY' подсказывает MySQL, чтобы выбрать следующий предстоящий 'd.eventDate'. Может быть, лучший способ –

ответ

2

Это всегда должно дать вам первое предстоящего события:

SELECT 
     e.id, 
     d.location_id, 
     d.eventDate 
FROM 
     event e 
      INNER JOIN eventDate d ON d.event_id = e.id 
WHERE 
     e.id = 5107 
     AND 
     d.id = (SELECT d1.id FROM eventDate d1 WHERE d1.event_id = 5107 AND d1.eventDate >= CURRENT_TIMESTAMP ORDER BY d1.eventDate ASC LIMIT 1) 

Но лучший способ, чтобы добавить LIMIT 1 к текущему запросу и удалению GROUP BY:

SELECT 
     e.id, 
     d.location_id, 
     d.eventDate 
FROM 
     event e 
      INNER JOIN eventDate d ON d.event_id = e.id AND d.eventDate >= CURRENT_TIMESTAMP 
WHERE 
     e.id = 5107 
ORDER BY 
     d.eventDate ASC 
LIMIT 1 
+0

это также возможно без подзапроса и просто добавление 'LIMIT' в первый запрос (тот, который он опубликовал), или я что-то упускаю? – Tikkes

+0

Нет, вы правы, я просто добавил это. Честно говоря, это лучший способ. – Manuel

+0

Решение, похоже, было бы неэффективным, представьте таблицу eventDate с миллионами строк, даже если бы я изменил ее на 'AND d.id = (SELECT d1.id ...)', решение two doen ' решить проблему «случайным образом или нет»? выбранные строки EventDate. Я получаю одну строку результатов уже (e.id = xx + GROUP BY e.id) –