#mysql #sql #mysql-8.0
#mysql #sql #mysql-8.0
Вопрос:
У меня есть таблица с именем tbl_device_log
. Он вставляет запись при запуске обновления в другую таблицу.
таблица модели
------------ ------------ ---------------------
| device_id | status | last_updated |
============ ============ =====================
| ab1 | S1 | 2020-10-05 10:00:00 |
------------ ------------ ---------------------
| ab2 | S1 | 2020-10-05 11:00:00 |
------------ ------------ ---------------------
| ab1 | S2 | 2020-10-05 12:00:00 |
------------ ------------ ---------------------
| ab2 | S2 | 2020-10-05 12:00:00 |
------------ ------------ ---------------------
| ab1 | S3 | 2020-10-05 14:00:00 |
------------ ------------ ---------------------
теперь я хочу, чтобы результирующий набор содержал статусы устройства в начале и в конце дня.
Нравится
------------ ------------ ----------------------
| device_id | status | last_status | date |
============ ============ ======================
| ab1 | S1 | S3 | 2020-10-05 |
------------ ------------ ----------------------
| ab2 | S1 | S2 | 2020-10-05 |
------------ ------------ ----------------------
Я попытался присоединиться к таблице в порядке возрастания и убывания следующим образом
select tbl_device_log.device_id, tbl_device_log.status, dl.status as last_status, date(tbl_device_log.last_updated) as date,tbl_
from tbl_device_log
join (select * from tbl_device_log group by device_id, date(last_updated) order by last_updated desc) as
dl ON (dl.device_id = tbl_device_log.device_id and date(dl.last_updated) = date(tbl_device_log.last_updated))
group by tbl_device_log.device_id, date(tbl_device_log.last_updated)
order by tbl_device_log.last_updated asc;
Но я получаю следующие данные
------------ ------------ ----------------------
| device_id | status | last_status | date |
============ ============ ======================
| ab1 | S1 | S1 | 2020-10-05 |
------------ ------------ ----------------------
| ab2 | S1 | S1 | 2020-10-05 |
------------ ------------ ----------------------
Что я делаю не так?
Комментарии:
1. Какая версия MySQL использовалась? Начиная с MySQL 8.0, здесь можно использовать оконные функции
2. @SlavaRozhnev Это 8.0.1
Ответ №1:
Я бы предложил оконные функции:
select dl.*
from (select dl.*,
row_number() over (partition by device_id, date(date) order by last_updated) as seqnum_asc,
row_number() over (partition by device_id, date(date) order by last_updated desc) as seqnum_desc
from tbl_device_log dl
) dl
where seqnum_asc = 1 or seqnum_desc = 1;
Комментарии:
1. Что
t
здесь?2. @prasadK . , , Теперь это последовательно
dl
, псевдоним таблицы для вашей таблицы.
Ответ №2:
Пожалуйста, проверьте следующий запрос как решение:
select distinct -- prevent duplicates
device_id,
-- get first status per device per day
first_value(status) over (PARTITION BY device_id, date(last_updated) order by last_updated asc) as status,
-- get last status per device per day
first_value(status) over (PARTITION BY device_id, date(last_updated) order by last_updated desc) as last_status,
date(last_updated) as date
from tbl_device_log;
Протестируйте DB fiddle на SQLize.online
Результат:
device_id status last_status date
ab1 S1 S3 2020-10-05
ab2 S1 S2 2020-10-05