0

我的数据如下所示:

id   int (11) primary key auto_increment
key  int (2)
type int (2)
data int (4)
timestamp datetime

有 5 种不同的键 - 1,2,3,4,5 和三种类型 - 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)

或类似的东西。当然,这还不算接近。我完全迷失了这个。感觉就像我需要按键分组,但语法让我难以理解。任何建议表示赞赏。

编辑:附加信息:

如果:“数据”是温度。'key' 是星期几。“类型”是早上、中午或晚上

所以数据可能看起来像

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 条数据求和。

4

3 回答 3

3

如果保证每个 ( , ) 的timestamp列都是唯一的(也就是说,有一个 UNIQUE 约束,那么这个查询将返回指定的结果集。(这不是唯一的方法,但它是一种熟悉的模式):keytypeON (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在该查询上添加 a,这不会改变结果,因为我们保证 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不是非法的,但这些标识符(通常)需要用反引号括起来。但是更改这些列的名称以使其不是保留字是最佳实践。

于 2013-08-14T21:47:07.180 回答
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小提琴

于 2013-08-14T21:45:15.253 回答
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;

编辑:子选择解决方案将是相似的,因为只有 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;

希望有帮助。

于 2013-08-14T21:44:44.633 回答