我有一张表格如下所示
state_history
+---------------------+-----------+----------------+ +
| state_added_time | entity_id | state_id | .... |
+---------------------+-----------+----------------+ |
| 2015-05-15 13:24:22 | 1 | 1 | |
| 2015-05-15 13:29:44 | 3 | 2 | |
| 2015-05-15 13:34:26 | 2 | 2 | |
| 2015-05-15 14:24:28 | 1 | 3 | |
| 2015-05-15 14:24:30 | 2 | 3 | |
| 2015-05-15 14:26:32 | 3 | 5 | |
| 2015-05-15 14:26:34 | 3 | 3 | |
.......
我的目的是在任何特定时间了解所有实体的状态。例如,如果从应用程序收到的时间戳为2015-05-15 14:25:00
,则预期输出应为:
state_history
+---------------------+-----------+----------------+ +
| state_added_time | entity_id | state_id | .... |
+---------------------+-----------+----------------+ |
| 2015-05-15 14:24:28 | 1 | 3 | |
| 2015-05-15 14:24:30 | 2 | 3 | |
| 2015-05-15 13:29:44 | 3 | 2 | |
.......
即,知道在给定时间之前或之后每个实体发生的最后状态变化。状态变化之间的间隔不固定。因此,我不能有2个时间边界,并在它们之间找到行。
我尝试使用TIMEDIFF
但未能获得所需的输出。有人可以指导我走的路吗?
编辑:感谢大家的快速回复。我尝试了答案,并注意到在实际数据库上执行时,查询需要花费大量时间来获取行。可能是因为字段entity_id
和state_id
是其他两个表的外键。
既然已知这有什么方法可以提高查询的性能吗?
答案 0 :(得分:3)
你在找这个吗?
SELECT h.*
FROM
(
SELECT entity_id, MAX(state_added_time) state_added_time
FROM state_history
WHERE state_added_time <= '2015-05-15 14:25:00'
GROUP BY entity_id
) q JOIN state_history h
ON q.entity_id = h.entity_id
AND q.state_added_time = h.state_added_time
输出:
| state_added_time | entity_id | state_id | |-----------------------|-----------|----------| | May, 15 2015 13:29:44 | 3 | 2 | | May, 15 2015 14:24:28 | 1 | 3 | | May, 15 2015 14:24:30 | 2 | 3 |
这是 SQLFiddle 演示
答案 1 :(得分:3)
为此,您可以使用一些简单的聚合。您只需要// Before all your routes
routeBuilder.MapRoute(
"Root",
"",
defaults: new { controller = "Home", action = "Index" });
// Your routes here
// After all your routes
routeBuilder.MapRoute(
"DeepLink",
"{*pathInfo}",
defaults: new { controller = "Home", action = "Index" });
函数来获取每个entity_id的最大时间,条件是它小于给定的时间戳。
一旦你有了每个entity_id的时间,你需要将它连接回原始表,以便获得state_id值。它看起来像这样:
MAX()
以下是SQL Fiddle示例。
答案 2 :(得分:3)
您也可以使用变量:
SELECT entity_id, state_added_time, state_id
FROM (
SELECT state_added_time, state_id,
@row_number:= CASE WHEN @entity = entity_id THEN @row_number+1
ELSE 1
END AS row_number,
@entity:=entity_id AS entity_id
FROM state_history
WHERE state_added_time <= '2015-05-15 14:25:00'
ORDER BY entity_id, state_added_time DESC ) t
WHERE t.row_number = 1
每次遇到新的@row_number
时, entity_id
都会被重置。在每个entity_id
中,@row_number = 1
的值指向最近的记录。
答案 3 :(得分:1)
从集合的角度考虑这一点。您需要一组包含最大日期的数据,该日期小于或等于按实体分组提供的日期。可以将这组数据生成为内联视图。 (我打电话给B)一旦你有了这个集合,就把它连接回基础集,把它连接回基集来获得额外的字段。
SaveChangesAsync
答案 4 :(得分:0)
尝试
SELECT * FROM state_history WHERE UNIX_TIMESTAMP(state_added_time) <= UNIX_TIMESTAMP('2015-05-15 14:25:00')
答案 5 :(得分:0)
不确定你是否可以做到
SELECT * From state_history where state_added_time <= '2015-05-15 14:25:00' ORDER BY state_added_time DESC
答案 6 :(得分:0)
SELECT s.*
from (select Max(state_added_time) AS maxts, entity_id
FROM state_history
WHERE state_added_time <= "2015-05-15 14:25:00"
GROUP BY entity_id
) as m inner join state_history s
on s.state_added_time = m.maxts
and s.entity_id = m.entity_id
sqlfiddle:http://sqlfiddle.com/#!9/884ee/12/0