объединить таблицу только с последними строками

0

Я знаю, что есть вопросы по одной теме, но я не мог понять.

Я следую этой ссылке и пробовал этот запрос:

    SELECT * FROM food_list f
    INNER JOIN (
            SELECT MAX(updated_on) max_row, rate, item_id
            FROM food_rate
            GROUP BY rate, item_id
        ) f_max ON (f_max.item_id = f.id)
    INNER JOIN food_rate fr ON (fr.updated_on = f_max.max_row);

Но я не получаю права на запись.

Вот моя таблица:

food_list:

id    |    item
----------------
1     |    pizza
2     |    burger
3     |    sandwich

food_rate:

id    |   item_id   |   rate   |   updated_on
----------------------------------------------
1     |    1        |   80     |   2018-06-01
2     |    2        |   90     |   2018-06-01
3     |    3        |   70     |   2018-06-01
4     |    1        |   60     |   2018-06-02

Я хочу получать записи с последней датой из food_rate для каждого элемента в food_list.

Здесь ожидаемый результат:

item_id   |  rate   |   updated_on
----------------------------------
1         |   60    |   2018-06-02
2         |   90    |   2018-06-01
3         |   70    |   2018-06-01
Теги:
aggregate-functions

2 ответа

1
Лучший ответ

Вы можете получить последние строки, используя коррелированный подзапрос:

select fr.*
from food_rate fr
where fr.updated_on = (select max(fr2.updated_on)
                       from food_rate fr2
                       where fr2.item_id = fr.item_id
                      );

Вы можете добавить join для фильтрации:

select fr.*
from food_list fl join
     food_rate fr
     on fr.item_id = fl.id
where fr.updated_on = (select max(fr2.updated_on)
                       from food_rate fr2
                       where fr2.item_id = fr.item_id
                      );

Вы можете использовать свой метод агрегирования, но он, вероятно, будет менее эффективным (с учетом соответствующих индексов), потому что join в food_list предположительно уменьшает количество строк. В условии on условие:

INNER JOIN
food_rate fr
ON fr.updated_on = f_max.max_row AND fr.item_id = f_max.item_id;
1

Вы хотите получать данные только из таблицы food_rate, поэтому вам не нужно ничего присоединяться. Выберите из food_rate где updated_on - максимальное значение updated_on для item_id:

select item_id, rate, updated_on
from food_rate
where (item_id, updated_on) in
(
  select item_id, max(updated_on)
  from food_rate
  group by item_id
);

Начиная с MySQL 8.0 вы также можете использовать для этого функцию окна, таким образом, считывая таблицу только один раз:

select item_id, rate, updated_on
from
(
  select
    item_id, rate, updated_on,
    max(updated_on) over (partition by item_id) as max_updated_on
  from food_rate
) rates
where updated_on = max_updated_on;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню