在 mysql 中以相反的顺序将 table 连接到自身

Join a table to itself in reverse order in mysql

我有一个 table 叫 tbl_device_log。它在另一个 table.

的更新触发器上插入一条记录

型号table

+------------+------------+---------------------+
| 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 |
+------------+------------+----------------------+

我试过像这样按升序和降序加入table

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 |
+------------+------------+----------------------+

我做错了什么?

我建议 window 函数:

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;

请检查下一个查询作为解决方案:

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;

测试数据库 fiddle SQLize.online

结果:

device_id    status    last_status    date
ab1          S1        S3             2020-10-05
ab2          S1        S2             2020-10-05