У меня есть SQL-запрос, который LEFT присоединяет к нему таблицу. Это приводит к дублированию строк из основной таблицы, но с разными строками из таблицы JOINed. Как выбрать строки с наивысшей датой из таблицы JOINed.
Вот пример (это результат моего запроса):
ID Message Date --------------------------- 0 Hi 2011-01-01 0 Bye 2011-02-05 0 Hello 2011-04-20 1 Test 2010-12-31 1 Testing 2010-11-15 2 Something 2010-12-12 2 Nothing 2011-01-01 2 Yes 2010-02-05 3 Cool NULL
Я хочу одну строку на ID, строку с самым высоким ID.
ID Message Date --------------------------- 0 Hello 2011-04-20 1 Test 2010-12-31 2 Nothing 2011-01-01 3 Cool NULL
Мой текущий запрос – это что-то вроде этого (я просто сделал это, но он похож на реальный):
SELECT t1.ID, t2.Message, t2.Date FROM t1 LEFT JOIN ( SELECT t3.ID, t3.message, t3.Date FROM t3 LEFT JOIN t4 ON t4.userID = 12 AND t3.ID = t4.ID WHERE t4.color = 'blue' ) AS t2 ON t1.ID = t2.ID WHERE t1.userID = 12
Думаю, я мог бы использовать PHP и пробивать результаты и выбирать те, которые мне нужны, но могу ли я сделать MySQL для меня?
EDIT : Извините, мой первый пример был неправильным, это больше похоже на то, что я хочу.
EDIT 2 : Я попытался использовать GROUP BY и MAX, но я думаю, что я делаю что-то неправильно.
Я пытался:
SELECT t1.ID, t2.Message, MAX(t2.Date) FROM t1 LEFT JOIN ( SELECT t3.ID, t3.message, t3.Date FROM t3 LEFT JOIN t4 ON t4.userID = 12 AND t3.ID = t4.ID WHERE t4.color = 'blue' ) AS t2 ON t1.ID = t2.ID WHERE t1.userID = 12 GROUP BY t1.ID
Но это дало мне:
ID Message Date --------------------------- 0 Hi 2011-04-20 1 Test 2010-12-31 2 Something 2011-01-01 3 Cool NULL
Как получить сообщение, связанное с самой высокой датой.
Как это:
SELECT t1.ID, t1.Message, MAX(t2.Date) as [Date] FROM t1 LEFT JOIN ( SELECT t3.ID, t3.Date FROM t3 LEFT JOIN t4 ON t4.userID = 12 AND t3.ID = t4.ID WHERE t3.color = 'blue' ) AS t2 ON t1.ID = t2.ID WHERE t1.userID = 12 GROUP BY t1.ID, t1.Message
Вы можете использовать GROUP BY
для группировки определенных значений с ограничением, которое вы должны группировать во всех значениях в списке выбора , если только это не функция агрегата , например MAX
.
Select t1.id, t1.Message, t3.date From t1 Left Join t3 On t3.id = t1.id And t3.id = ( Select Max( t3_1.Id ) From t3 As t3_1 Where t3_1.id = t3.id Having Max( t3_1.date ) = t3.date ) Where t1.userID = 12
Насколько я могу судить, соединение с t4
играет никакой роли в запросе. Он не фильтрует результаты и ничего не отображается из таблицы t4
отображаемой в предложении Select. Кроме того, я предположил, что столбец t3.id
фактически является внешним ключом таблицы t1
а не основным ключом. Если это первичный ключ, то другой фильтр для максимальной даты не нужен.
Обновить данный вопрос
Добавляя критерии к предложению Where на t4
, вы фактически превратили его в внутреннее соединение. Тем не менее, одним из решений является:
Select t1.id, t3.Message, t3.date From t1 Left Join t3 On t3.id = t1.id And t3.id = ( Select Max( t3_1.Id ) From t3 As t3_1 Join t4 On t4.id = t3_1.id Where t4.color = 'blue' And t3_1.id = t3.id Having Max( t3_1.date ) = t3.date ) Where t1.userID = 12