0

次のようなデータがあります。

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

1、2、3、4、5 の 5 つの異なるキーと、1、2、3 の 3 種類のキーがあります。

データは、特定のタイプのキーに対して継続的に挿入されます。

抽出する必要があるのは、5 つのキー (1,2,3,4,5) すべての特定のタイプ (タイプ 1 など) のデータの合計であるため、正確に 5 つのレコードの合計です。各キーのデータの最新 (max(timestamp) 値 (5 個あります)) のみを合計したいのですが、タイムスタンプがすべて異なる場合があります。

このようなもの....

SELECT sum(data) FROM table WHERE type='1' AND timestamp=(SELECT max(timestamp FROM table WHERE type='1' GROUP BY key)

またはそのようなもの。もちろん、それは近いことではありません。私はこれで完全に迷っています。キーでグループ化する必要があるように感じますが、構文がわかりません。任意の提案をいただければ幸いです。

編集:追加情報:

if: 'data' は温度です。「キー」は曜日です。「タイプ」は朝、昼、夜

したがって、データは次のようになります

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)

これらがタイムスタンプ順 (降順) であり、5 日間すべての最新の正午の温度の合計が必要な場合、結果は次のようになります。この場合、最後の正午も火曜日であり、それよりも早いため含まれていないため、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 つのキー値すべてに対して type=1mの「最新」を返しtimestampます (少なくとも 1 つの行が存在する場合)。

それは元のテーブルに結合され、その「最新」のタイムスタンプを持つ行を取得します。

、、の先頭列を持つ適切なインデックスによりtype、パフォーマンスが向上する可能性があります。keytimestamp

(これは、仕様に関する私の理解に基づいています。仕様について完全に明確ではない場合があります。このクエリが行っているのは、type=1行の最新のタイムスタンプを取得することです。同じ最新のタイムスタンプを持つ行が 2 つ (またはそれ以上) ある場合指定されたキーとタイプの値の場合、このクエリはそれらの行の両方 (またはすべて) を取得し、それらを合計に含めます。

GROUP BY t.typet.type が定数 1 (インライン ビュー クエリの WHERE 句の述語で指定) と等しいことが保証されているため、そのクエリにa を追加しても結果は変わりません。

ただし、同じクエリで 3 つのタイプすべての合計を取得する場合は、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

ノート:

予約語を識別子として使用すること (たとえばTIMESTAMPandKEYは違法ではありませんが、これらの識別子は (通常) バッククォートで囲む必要があります。ただし、予約語にならないようにこれらの列の名前を変更することをお勧めします。

于 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;

編集: 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;

それが役立つことを願っています。

于 2013-08-14T21:44:44.633 に答える