如何选择每个项目具有最大时间戳的行集?
Posted
技术标签:
【中文标题】如何选择每个项目具有最大时间戳的行集?【英文标题】:How can I select the set of rows where each item has the greatest timestamp? 【发布时间】:2015-12-09 01:01:15 【问题描述】:使用 Sqlite,我想获取具有最大时间戳的行的集合。该表包含项目的属性,即键值对和时间戳。我想为每个属性选择最新的值。
考虑以下简化的架构和数据:
CREATE TABLE Properties (thing VARCHAR,
key VARCHAR,
value VARCHAR,
timestamp INT);
INSERT INTO Properties VALUES ("apple", "color", "red", 0);
INSERT INTO Properties VALUES ("apple", "taste", "sweet", 0);
INSERT INTO Properties VALUES ("apple", "size", "small", 0);
INSERT INTO Properties VALUES ("watermelon", "taste", "sweet", 0);
INSERT INTO Properties VALUES ("watermelon", "size", "large", 0);
INSERT INTO Properties VALUES ("watermelon", "color", "pink", 1);
INSERT INTO Properties VALUES ("watermelon", "color", "green", 0);
我想为 thing="watermelon"
编写一个查询,返回:
taste|sweet
size|large
color|pink
注意有两行key="color"
,查询返回timestamp
值最大的行。此外,一个属性的最大 timestamp
可能与另一个属性不同。
到目前为止我尝试过的包括:
获取thing="watermelon"
的属性集:
SELECT DISTINCT(key) FROM Properties WHERE thing='watermelon';
为thing="watermelon"
获取key="color"
的最新值:
SELECT *
FROM Properties
WHERE thing='watermelon'
AND key='color'
ORDER BY timestamp DESC
LIMIT 1;
但我不知道如何将两者结合起来。我可能是从命令式编程的角度来解决这个问题的,这就是为什么我会感谢帮助。
【问题讨论】:
【参考方案1】:在 SQLite 3.7.11 或更高版本中,您可以简单地使用 MAX() 从组中选择一行:
SELECT key, value, MAX(timestamp)
FROM Properties
WHERE thing = 'watermelon'
GROUP BY key;
【讨论】:
SQLite 如何知道选择对应于最大时间戳的value
?如果查询是select key, value, max(timestamp), min(timestamp)
,那么查询会返回哪个value
?
然后它随机选择这两行之一。
它不会仍然在您的查询中选择一个随机的value
行吗?我不确定sqlite,但这是mysql中的常见错误,因为根据mysql文档,允许引擎在选择不在组中的列时返回一个随机值,但实际上它通常返回与之关联的列最大/最小等,所以人们认为这就是它的工作原理。但是这种行为可能会逐个版本地改变。 ***.com/questions/1752556/…
SQLite 保证其他列的值来自与 MIN()/MAX() 匹配的行。
当有MIN()/MAX()时,选择is not arbitrary。【参考方案2】:
调整找到here的查询,我想出了以下内容:
SELECT a.*
FROM Properties AS a
INNER JOIN (
SELECT key, MAX(timestamp) AS max_timestamp
FROM Properties
WHERE thing='watermelon'
GROUP BY key) b
ON a.key = b.key AND a.timestamp = b.max_timestamp
WHERE thing='watermelon';
似乎有效,但我对 cmets 这个查询的优点/缺点感兴趣。
【讨论】:
【参考方案3】:使用HAVING
获得简单易读的解决方案:
SQLFiddleDemo
SELECT *
FROM Properties
WHERE thing = "watermelon"
GROUP BY thing, key
HAVING timestamp = MAX(timestamp)
【讨论】:
投反对票有什么特别的原因吗?如果这个解决方案有什么错误,我会很高兴听到它。以上是关于如何选择每个项目具有最大时间戳的行集?的主要内容,如果未能解决你的问题,请参考以下文章