Need to group by the vehicle id from the online & offline date history logs and get the latest date of history

huangapple go评论67阅读模式
英文:

Need to group by the vehicle id from the online & offline date history logs and get the latest date of history

问题

以下是翻译好的部分:

我有以下表格

  1. tbl_vehicles
vid accnt_id platenumber
1 1 VD101
2 1 VD102
  1. tbl_status_history
id vid accnt_id date_online date_offline
1 1 1 2023-02-25 0000-00-00
2 1 1 0000-00-00 2023-02-26
3 2 1 0000-00-00 2023-02-27
4 2 1 0000-00-00 2023-02-28
5 1 1 0000-00-00 2023-03-01
6 1 1 2023-03-02 0000-00-00

现在,我需要按vid分组,并获取它们的最新状态历史记录。例如,在vid:1下的tbl_status_history中,该vid的最新状态历史记录是在线的,所以vid 1的结果将是日期date_online 2023-03-02。

以下是我的目标结果。

id vid accnt_id date_online date_offline
2 1 1 2023-03-02 0000-00-00
4 2 1 0000-00-00 2023-02-28

我使用了@nnichols的代码,并将其更新为下面的代码,以便获取最新的在线日期,但还没有弄清楚如何在分组之前对两个日期(Online和offline)进行排序

SELECT h.id, h.vid, h.accnt_id, h.date_online, h.date_offline, v.platenumber
FROM tbl_status_history h
JOIN (
    SELECT vid, MAX(date_offline) max_date_offline, MAX(date_online) max_date_online
    FROM tbl_status_history
    GROUP BY vid
) h2 ON h.vid = h2.vid AND h.date_offline = h2.max_date_offline and h.date_online = h2.max_date_online
JOIN tbl_vehicles v ON h.vid = v.vid and h.accnt_id = 1;
英文:

I have below the tables

  1. tbl_vehicles
vid accnt_id platenumber
1 1 VD101
2 1 VD102
  1. tbl_status_history
id vid accnt_id date_online date_offline
1 1 1 2023-02-25 0000-00-00
2 1 1 0000-00-00 2023-02-26
3 2 1 0000-00-00 2023-02-27
4 2 1 0000-00-00 2023-02-28
5 1 1 0000-00-00 2023-03-01
6 1 1 2023-03-02 0000-00-00

Now, I need to group the vid and get their latest status history. For example in vid:1 under tbl_status_history. This vid latest status history is online so the result for vid 1 would be the date_online 2023-03-02.

Below is my target result.

id vid accnt_id date_online date_offline
2 1 1 2023-03-02 0000-00-00
4 2 1 0000-00-00 2023-02-28

I used the code of @nnichols and updated it to the below code to get also the latest online date but had still not worked out how to sort the two dates(Online & offline) before the group by

SELECT h.id, h.vid, h.accnt_id, h.date_online, h.date_offline, v.platenumber
FROM tbl_status_history h
JOIN (
    SELECT vid, MAX(date_offline) max_date_offline, MAX(date_online) max_date_online
    FROM tbl_status_history
    GROUP BY vid
) h2 ON h.vid = h2.vid AND h.date_offline = h2.max_date_offline and h.date_online = h2.max_date_online
JOIN tbl_vehicles v ON h.vid = v.vid and h.accnt_id = 1;

答案1

得分: 0

以下是已翻译的部分:

这是使用 ROW_NUMBER() 生成 "目标结果" 的一种方法:

SELECT h.id, h.vid, h.accnt_id, h.date_online, h.date_offline, v.platenumber
FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY vid ORDER BY GREATEST(date_online, date_offline) DESC) rn
    FROM tbl_status_history
    WHERE accnt_id = 1
) h
JOIN tbl_vehicles v ON h.vid = v.vid
WHERE h.rn = 1;

或者,使用 MySQL 8 之前的方法:

SELECT h.id, h.vid, h.accnt_id, h.date_online, h.date_offline, v.platenumber
FROM tbl_status_history h
JOIN (
    SELECT vid, GREATEST(MAX(date_offline), MAX(date_online)) max_date
    FROM tbl_status_history
    WHERE accnt_id = 1
    GROUP BY vid
) h2 ON h.vid = h2.vid AND (h.date_offline = h2.max_date OR h.date_online = h2.max_date)
JOIN tbl_vehicles v ON h.vid = v.vid;

你应该考虑更改 tbl_status_history 的结构:

id vid status date
1 1 online 2023-02-25
2 1 offline 2023-02-26
3 2 offline 2023-02-27
4 2 offline 2023-02-28
5 1 offline 2023-03-01
6 1 online 2023-03-02
  • accnt_idtbl_vehicles 中,应该在那里,所以这里是多余的。
  • 使用两个 DATE 列来存储一个 状态变更日期 是没有意义的。
  • 你可以考虑删除 id,以使用自然键,但我可能不会走那么远。
英文:

This is one way to produce your "target result" using ROW_NUMBER():

SELECT h.id, h.vid, h.accnt_id, h.date_online, h.date_offline, v.platenumber
FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY vid ORDER BY GREATEST(date_online, date_offline) DESC) rn
    FROM tbl_status_history
    WHERE accnt_id = 1
) h
JOIN tbl_vehicles v ON h.vid = v.vid
WHERE h.rn = 1;

Or, the pre MySQL 8 method:

SELECT h.id, h.vid, h.accnt_id, h.date_online, h.date_offline, v.platenumber
FROM tbl_status_history h
JOIN (
    SELECT vid, GREATEST(MAX(date_offline), MAX(date_online)) max_date
    FROM tbl_status_history
    WHERE accnt_id = 1
    GROUP BY vid
) h2 ON h.vid = h2.vid AND (h.date_offline = h2.max_date OR h.date_online = h2.max_date)
JOIN tbl_vehicles v ON h.vid = v.vid;

You should consider changing the structure of tbl_status_history to:

id vid status date
1 1 online 2023-02-25
2 1 offline 2023-02-26
3 2 offline 2023-02-27
4 2 offline 2023-02-28
5 1 offline 2023-03-01
6 1 online 2023-03-02
  • accnt_id is in tbl_vehicles, where it belongs, so redundant here
  • two DATE columns to store one status change date does not make sense
  • you could drop id too, in favour of the natural key, bit I probably wouldn't go that far

huangapple
  • 本文由 发表于 2023年3月1日 16:36:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/75601259.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定