我有一个记录表和一个历史记录表,它们在记录流过我们的系统时添加时间戳。他们看起来像这样...
records
+------+-----------+----+
| id | name | ...|
+------+-----------+----+
| 1 | host1 | ...|
| 2 | host2 | ...|
| 3 | host3 | ...|
| 4 | host4 | ...|
+------+-----------+----+
history
+----+-----------+------------+--------+--------+
| id | record_id | timestamp | module | status |
+----+-----------+------------+--------+--------+
| 5 | 1 | 2019-01-01 | eng | new |
| 6 | 1 | 2019-01-03 | eng | done |
| 7 | 2 | 2019-01-01 | eng | new |
| 8 | 2 | 2019-01-04 | eng | done |
| 9 | 3 | 2019-01-02 | eng | new |
+----+-----------+------------+--------+--------+
由于记录表可能包含或可能不包含许多不同的模块和状态条目,因此大大简化了此过程,具体取决于记录工作流程。我需要的是一个记录列表,以及NEW和DONE的时间戳(如果它们存在的话)或null(如果不存在的话),像这样...
+------+-----------+----------------+---------------+
| id | name | eng_start_time | eng_end_time |
+------+-----------+----------------+---------------+
| 1 | host1 | 2019-01-01 | 2019-01-03 |
| 2 | host2 | 2019-01-01 | 2019-01-04 |
| 3 | host3 | 2019-01-02 | null |
| 4 | host4 | null | null |
+------+-----------+----------------+---------------+
我能够通过使用2个子查询来获得这些结果,但是我担心由于这些表变得非常大,这样做可能没有效率。这是我的查询有效。有没有一种方法可以通过更有效的联接/子选择来获得这些结果?
select r.id, r.name,
(select timestamp from history where request_id = r.id and module="eng" and status="new") as eng_start_time,
(select timestamp from history where request_id = r.id and module="eng" and status="done") as eng_end_time
from records r order by r.id
答案 0 :(得分:1)
您似乎需要一些LEFT JOIN:
select r.id, r.name, hs.timestamp as eng_start_time, he.timestamp as eng_end_time
from records r
left join history hs on r.id = hs.request_id and hs.module="eng" and hs.status="new"
left join history he on r.id = he.request_id and he.module="eng" and he.status="done"
order by r.id
答案 1 :(得分:1)
您可以通过左两个JOIN
来实现。
select r.id, r.name, h_start.timestamp eng_start_time, h_end.timestamp eng_end_time
from records r
left join history h_start
ON h_start.request_id = r.id AND h_start.module='eng' AND h_start.status='new'
left join history h_end
ON h_end.request_id = r.id AND h_end.module='eng' AND h_end.status='done'
order by r.id
注意:我用双引号替换了双引号,这是SQL中的一种更好的做法。