我在使用select语句从'next'行检索信息时遇到问题。我在MySQL中有一个表,其中包含状态信息(打开或关闭),示例记录如下:
状态表:(id是自动增量)
+-----+----------+----------+---------------------+
| id | asset_id | state_id | created |
+-----+----------+----------+---------------------+
| 917 | 97 | 1 | 2013-10-13 22:07:03 |
| 918 | 97 | 0 | 2013-10-13 22:09:34 |
| 919 | 97 | 1 | 2013-10-13 22:09:52 |
| 924 | 97 | 0 | 2013-10-14 10:39:24 |
| 939 | 97 | 1 | 2013-10-14 12:47:26 |
| 940 | 97 | 0 | 2013-10-14 12:47:27 |
+-----+----------+----------+---------------------+
我需要做的是提出一个声明,告诉我在给定日期内每个资产的状态转换开始和结束时间,如下所示: 结束时间始终是下一个状态的开始时间。如果一天中的最后一个状态一直持续到第二天,我会将其报告为结束时间:
+----------+---------------------+---------------------+
| state_id | starttime | endtime |
+----------+---------------------+---------------------+
| 1 | 2013-10-13 22:07:03 | 2013-10-13 22:09:34 |
| 0 | 2013-10-13 22:09:34 | 2013-10-13 22:09:52 |
| 1 | 2013-10-13 22:09:52 | 2013-10-14 10:39:24 |
+----------+---------------------+---------------------+
这是我目前的陈述:
SELECT t1.state_id, t1.created as starttime, t2.created as endtime
FROM state t1, state t2
WHERE t1.created like "2013-10-13%" and t1.asset_id=97 and t2.created =
(SELECT min(created) FROM state
WHERE id > t1.id and asset_id = 97 order by created desc);
当请求的日期不是结果集的最后一天时(例如“2013-10-13”的示例),这可以正常工作。问题是最后一天和最后一个状态(最后一个记录)。 如果我运行2013-10-14的示例数据,我只获得两个状态转换而不是三个:
+----------+---------------------+---------------------+
| state_id | starttime | endtime |
+----------+---------------------+---------------------+
| 0 | 2013-10-14 10:39:24 | 2013-10-14 12:47:26 |
| 1 | 2013-10-14 12:47:26 | 2013-10-14 12:47:27 |
+----------+---------------------+---------------------+
最后一个被丢弃的大概是因为子查询的where子句'id> t1.id”。 创建的记录“2013-10-14 12:47:27”是表格中的最后一个,并且在获取结束时间之后没有其他记录。
我的问题是: 是否可以更改查询,以便它也选择最后一个转换,例如使用NULL作为结束时间,如下所示:
+----------+---------------------+---------------------+
| state_id | starttime | endtime |
+----------+---------------------+---------------------+
| 0 | 2013-10-14 10:39:24 | 2013-10-14 12:47:26 |
| 1 | 2013-10-14 12:47:26 | 2013-10-14 12:47:27 |
| 0 | 2013-10-14 12:47:27 | NULL |
+----------+---------------------+---------------------+
答案 0 :(得分:0)
更改
and t2.created =
(SELECT min(created) FROM state
WHERE id > t1.id and asset_id = 97 order by created desc);
到
and (t2.created =
(SELECT min(created) FROM state
WHERE id > t1.id and asset_id = 97 order by created desc))
or t2.created is NULL;
除非有其他条件会导致t2.created为NULL并且您不想要该记录,否则这将无效。
答案 1 :(得分:0)
你需要LEFT JOIN。试试这个。你可以在这里看到它:http://sqlfiddle.com/#!2/c9cb7/2
SELECT t1.state_id, t1.created as starttime, t2.created as endtime
FROM state t1
LEFT JOIN state t2
ON t1.asset_id = t2.asset_id
AND t1.created < t2.created
WHERE t1.created like "2013-10-13%" and t1.asset_id=97
AND NOT EXISTS
(SELECT *
FROM state
WHERE state.created > t1.created
AND state.created < t2.created)
ORDER BY starttime