如何获得多个键的列总和?

时间:2013-08-14 21:13:58

标签: mysql

我的数据如下:

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个数据。

3 个答案:

答案 0 :(得分:3)

如果timestamp列保证每个列都是唯一的(keytype)(也就是说,有一个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

加入原始表,以检索具有“最新”时间戳的行。

包含typekeytimestamp的前导列的合适索引可能会提高效果。

(这是基于我对规范的理解;我可能不完全清楚规范。这个查询正在做的是获取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

注意:

使用保留字作为标识符(例如TIMESTAMPKEY并非违法,但这些标识符(通常)需要包含在反引号中。但是更改这些列的名称以便它们不是保留字是最佳做法。

答案 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;

这可能会成功......

SQL-Fiddle

答案 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;

希望有所帮助。