Выберите строки из одной таблицы, объедините самую последнюю строку из другой таблицы с отношением один ко многим
Что я хотел бы сделать, это выбрать определенный набор строк из одной таблицы (таблица A) и объединить с другой таблицей (таблица B), так что только одна запись появится из таблицы A, объединенная с самой последней записью из таблицы B на основе столбца даты и времени.
Например, таблица A имеет такую структуру (сильно упрощенная):
id | col_1 | col_2
---+-----------+----------------
1 | something | something else
2 | val_1 | val_2
3 | stuff | ting
4 | goats | sheep
И таблица B выглядит так:
id | fk_A | datetime_col | col_3
---+-----------+---------------------+--------
1 | 1 | 2012-02-01 15:42:14 | Note 1
2 | 1 | 2012-02-02 09:46:54 | Note 2
3 | 1 | 2011-11-14 11:18:32 | Note 3
4 | 2 | 2009-04-30 16:49:01 | Note 4
5 | 4 | 2013-06-21 15:42:14 | Note 5
6 | 4 | 2011-02-01 18:44:24 | Note 6
То, что я хотел бы, это набор результатов, который выглядит следующим образом:
id | col_1 | col_2 | datetime_col | col_3
---+-----------+----------------+---------------------+--------
1 | something | something else | 2012-02-02 09:46:54 | Note 2
2 | val_1 | val_2 | 2009-04-30 16:49:01 | Note 4
3 | stuff | ting | NULL | NULL
4 | goats | sheep | 2013-06-21 15:42:14 | Note 5
Таким образом, вы можете видеть, что таблица B была объединена с таблицей A наB.fk_A = A.id
, но только самая последняя соответствующая запись из B была включена в результаты.
Я пробовал различные комбинацииSELECT DISTINCT
, LEFT JOIN
и подзапросов, и я просто не могу заставить его работать, я либо не получаю результатов или что-то вроде этого:
id | col_1 | col_2 | datetime_col | col_3
---+-----------+----------------+---------------------+--------
1 | something | something else | 2012-02-01 15:42:14 | Note 1
1 | something | something else | 2012-02-02 09:46:54 | Note 2
1 | something | something else | 2011-11-14 11:18:32 | Note 3
2 | val_1 | val_2 | 2009-04-30 16:49:01 | Note 4
3 | stuff | ting | NULL | NULL
4 | goats | sheep | 2013-06-21 15:42:14 | Note 5
4 | goats | sheep | 2011-02-01 18:44:24 | Note 6
... с записями из таблицы А повторяется.
Очевидно, что мой SQL-фу недостаточно хорош для этой задачи, поэтому я был бы очень признателен, если бы один из вас, добрые люди, указал мне правильное направление. Я провел довольно много поиска и поиска по SO, и я не нашел ничего, что соответствовало бы этой конкретной задаче, хотя я уверен, что вопрос задавался ранее - я подозреваю, что есть ключевое слово SQL, которое я забыл / не знаю и если бы я искал это, я бы нашел ответ немедленно.
думаюэтот вопрос имеет дело с той же проблемой, хотя я не уверен на 100%, и принятый ответ включаетSELECT TOP
, который я думал (?) был недействительным в MySQL.
Поскольку мой фактический запрос намного сложнее и объединяет несколько таблиц, я покажу его на случай, если это как-то повлияет на то, как это делается:
SELECT `l` . * , `u`.`name` AS 'owner_name', `s`.`name` AS 'acquired_by_name', `d`.`type` AS `dtype` , `p`.`type` AS `ptype`
FROM `leads` l
LEFT JOIN `web_users` u ON `u`.`id` = `l`.`owner`
LEFT JOIN `web_users` s ON `s`.`id` = `l`.`acquired_by`
LEFT JOIN `deal_types` d ON `d`.`id` = `l`.`deal_type`
LEFT JOIN `property_types` p ON `p`.`id` = `l`.`property_type`
Этот запрос работает и возвращает нужные мне данные (иногда я также добавляюWHERE
оговорка, но это работает нормально), но я бы сейчас хотел:
LEFT JOIN `notes` n ON `n`.`lead_id` = `l`.`id`
...гдеnotes
содержит "много записей" иleads
содержит «одну запись», к которой они относятся.
Следует также отметить, что потенциально я также хотел бы вернуть самую старую запись (в другом запросе), но я представляю, что это будет простой случай инвертирования ASC / DESC где-то или что-то аналогичное простое.