如何选择每个项目具有最大时间戳的行集?

时间:2015-09-12 16:04:53

标签: sql sqlite greatest-n-per-group

使用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';

获取key="color"的最新值thing="watermelon"

SELECT * 
FROM Properties
WHERE thing='watermelon'
  AND key='color'
ORDER BY timestamp DESC
LIMIT 1;

但我无法弄清楚如何将两者结合起来。我可能从命令式编程角度来看这个,这就是为什么我会感谢你们的帮助。

3 个答案:

答案 0 :(得分:4)

在SQLite 3.7.11或更高版本中,您只需使用MAX()从一个组中选择一行:

SELECT key, value, MAX(timestamp)
FROM Properties
WHERE thing = 'watermelon'
GROUP BY key;

答案 1 :(得分:1)

调查发现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';

似乎可行,但我对这个查询的优点/缺点感兴趣。

答案 2 :(得分:0)

使用HAVING获得简单易读的解决方案:

<强> SQLFiddleDemo

SELECT *
FROM Properties
WHERE thing = "watermelon"
GROUP BY thing, key
HAVING timestamp = MAX(timestamp)