#mysql #sql
#mysql #sql
Вопрос:
Мне трудно разобраться в том, что, по-видимому, должно быть простым запросом.
Итак, допустим, у нас есть таблица, которая отслеживает количество виджетов / воздушных шаров в каждом хранилище по дате. Как бы вы получили список магазинов и их последнее количество виджетов / воздушных шаров?
т. е.
mysql> SELECT * FROM inventory;
---- ------------ ------- --------- ---------
| id | invDate | store | widgets | balloons|
---- ------------ ------- --------- ---------
| 1 | 2011-01-01 | 3 | 50 | 35 |
| 2 | 2011-01-04 | 2 | 50 | 35 |
| 3 | 2013-07-04 | 3 | 12 | 78 |
| 4 | 2020-07-04 | 2 | 47 | 18 |
| 5 | 2020-08-06 | 2 | 16 | NULL |
---- ------------ ------- --------- ---------
5 rows in set (0.00 sec)
Хотелось бы, чтобы в таблице результатов были перечислены все хранилища и их последний инвентарь виджетов / шариков
магазин, последние виджеты, последние шары
------- ----------- ---------
| store | widgets | baloons |
------- ----------- ---------
| 2 | 16 | NULL |
| 3 | 12 | 78 |
------- ----------- ---------
или возьмите последнее ненулевое значение для balloons.
Комментарии:
1. Добавьте ПОРЯДОК По invDate DESC и ГРУППУ По хранилищу в конец вашего запроса.
2. @jhilgeman: Это не так просто
3. @meccooll: Какую версию MySQL вы используете?
4. Запущено несколько версий, и их можно обновить, если есть элегантное решение для более новой версии, но одним из старых экземпляров является mysqld версии 5.7.31-0ubuntu0.16.04.1 для Linux на x86_64
Ответ №1:
Это работает для всех версий MySQL
select i.*
from inventory i
join
(
select store, max(invDate) as maxDate
from inventory
group by store
) tmp on tmp.store = i.store
and tmp.maxDate = i.invDate
С MySQL 8 вы можете выполнять оконные функции:
with cte as
(
select store, widgets, balloons,
ROW_NUMBER() OVER(PARTITION BY store ORDER BY invDate desc) AS rn
from inventory
)
select * from cte where rn = 1
Комментарии:
1. Вот и все! Приятно сознавать, что не было какой-то простой функции, которую я упускал. Спасибо
Ответ №2:
Вы можете использовать коррелированный подзапрос, чтобы получить последнюю запись для каждого хранилища
select i.*
from inventory i
where i.invDate = (
select max(invDate)
from inventory
where i.store = store
)
order by i.store
Комментарии:
1. @juergend вот так sqlfiddle.com /#!9/f845d7/1 ? Я действительно не понимаю вашего заявления, оно должно сработать, если дата 2 или более хранилищ одинакова из-за коррелированного запроса