我的数据如下:
id int (11) primary key auto_increment
key int (2)
type int (2)
data int (4)
timestamp datetime
有5种不同的键 - 1,2,3,4,5和3种类型 - 1,2,3
数据是针对密钥和特定类型连续输入的。
我需要提取的是所有5个键(1,2,3,4,5)中特定类型(例如,类型1)的数据总和,因此它恰好是5个记录的总和。我只想总结每个键的最新(最大(时间戳)值(有5个)数据,但它们可能都有不同的时间戳。
像这样......
SELECT sum(data) FROM table WHERE type='1' AND timestamp=(SELECT max(timestamp FROM table WHERE type='1' GROUP BY key)
或类似的东西。那当然不是很接近。我完全迷失在这一个。感觉就像我需要按键分组,但语法不适合我。任何建议表示赞赏。
编辑:其他信息:
if:'data'是温度。 'key'是星期几。 'type'是早晨,中午或晚上
所以数据可能看起来像
morning mon 70 (timestamp)
noon tue 78 (timestamp)
morning wed 72 (timestamp)
night tue 74 (timestamp)
morning thu 76 (timestamp)
noon wed 77 (timestamp)
night fri 78 (timestamp)
noon tue 79 (timestamp)
如果这些是时间戳顺序(desc)并且我想要所有五天的最近中午临时值的总和,结果将是:155,在这种情况下,因为最后一个中午也是星期二,它是更早,因此,不包含。合理?我想要任何密钥,特定类型,最新时间戳的“数据”总和。在这个例子中,我将总计最多7个数据。
答案 0 :(得分:3)
如果timestamp
列保证每个列都是唯一的(key
,type
)(也就是说,有一个UNIQUE约束ON (key,type,timestamp)
,那么此查询将返回指定的结果集。(这不是唯一的方法,但它是一种熟悉的模式):
SELECT SUM(t.data) AS latest_total
FROM mytable t
JOIN ( SELECT h.type
, h.key
, MAX(h.timestamp) AS max_ts
FROM mytable h
WHERE h.type='1'
GROUP
BY h.type
, h.key
) m
ON m.type = t.type
AND m.key = t.key
AND m.max_ts = t.timestamp
为所有5个键值(如果至少存在一行),为m
指定别名的内联视图会返回type = 1的“最新”timestamp
加入原始表,以检索具有“最新”时间戳的行。
包含type
,key
,timestamp
的前导列的合适索引可能会提高效果。
(这是基于我对规范的理解;我可能不完全清楚规范。这个查询正在做的是获取type=1
行的最新时间戳。如果碰巧有两个(或者对于给定键和类型具有相同最新时间戳值的行,此查询将检索这些行中的所有行(或所有行),并将它们包括在总和中。
我们可以在该查询上添加GROUP BY t.type
,这不会改变结果,因为我们可以保证t.type将等于常量1(在WHERE子句的谓词中指定)内联视图查询。)
但是如果我们想在同一个查询中获得所有三种类型的总数,我们需要添加GROUP BY:
SELECT t.key
, SUM(t.data) AS latest_total
FROM mytable t
JOIN ( SELECT h.type
, h.key
, MAX(h.timestamp) AS max_ts
FROM mytable h
WHERE h.type IN ('1','2','3')
GROUP
BY h.type
, h.key
) m
ON m.type = t.type
AND m.key = t.key
AND m.max_ts = t.timestamp
GROUP
BY t.key
注意:强>
使用保留字作为标识符(例如TIMESTAMP
和KEY
并非违法,但这些标识符(通常)需要包含在反引号中。但是更改这些列的名称以便它们不是保留字是最佳做法。
答案 1 :(得分:1)
SELECT SUM(data)
FROM ( SELECT CONCAT(MAX(timestamp), '_', type) AS customId
FROM table
WHERE type = '1'
GROUP BY key ) a
JOIN table b ON a.customId = CONCAT(b.timestamp, '_', type)
GROUP BY type;
这可能会成功......
答案 2 :(得分:0)
我希望简单性和可维护性使用临时表并用几个语句填充它。 “union-subselect”的解决方案对我来说看起来有点长。
所以
drop tamporary table if exists tmp_data;
create temporary table tmp_data (type int, value int);
insert into tmp_data select 1, value from data_table where type=1 order by timestamp desc limit 5;
insert into tmp_data select 2, value from data_table where type=2 order by timestamp desc limit 5;
insert into tmp_data select 3, value from data_table where type=3 order by timestamp desc limit 5;
select type, sum(value) as total from tmp_data group by type;
编辑: subselect-solution将是类似的,因为只有3种类型不太糟糕
select type, sum(value) as total from
(select 1 as type, value from data_table where type=1 order by timestamp desc limit 5
union
select 2 as type, value from data_table where type=2 order by timestamp desc limit 5
union
select 3 as type, value from data_table where type=3 order by timestamp desc limit 5) as subtab group by type;
希望有所帮助。