英文:
Need to group by the vehicle id from the online & offline date history logs and get the latest date of history
问题
以下是翻译好的部分:
我有以下表格
- tbl_vehicles
vid | accnt_id | platenumber |
---|---|---|
1 | 1 | VD101 |
2 | 1 | VD102 |
- 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
- tbl_vehicles
vid | accnt_id | platenumber |
---|---|---|
1 | 1 | VD101 |
2 | 1 | VD102 |
- 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_id
在tbl_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 intbl_vehicles
, where it belongs, so redundant here- two
DATE
columns to store onestatus 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论