1

行を前の行JOINと比較するために、テーブルをそれ自体に作成し、前のid(主キー)と比較しています。

CREATE TABLE `tablename` (
    id INT(5) PRIMARY KEY AUTO_INCREMENT,
    data INT
);

SELECT t1.id, t1.data, t1.data-(SELECT data FROM tablename WHERE id=t1.id-1) AS diff
FROM tablename t1 LEFT JOIN tablename t2 ON t1.id = t2.id
ORDER BY diff DESC LIMIT 1;

これをデータの特定のサブセットのみに制限するにはどうすればよいですか?たとえば、列user VARCHAR(32)がテーブルに追加された場合、特定のユーザーのみを比較するようにクエリを制限するにはどうすればよいですか?SELECT前提全体がシーケンシャルに依存するため、2つのクエリに単純なWHERE句を追加しても機能しませんid。データを一時テーブルに移動できると思いますが、よりクリーンで効率的なソリューションがある場合は、それを使用します。

私の意図はWHERE user='someUser'、diffがテーブル全体ではなく、特定のユーザーに対してのみdiffする句を追加することです。

これが動作するsqlfiddleです。このクエリを変更して、に対してのみ機能するWHERE name='a'ようにし、結果が。になるようにしますid=9, data=305, diff=125

4

5 に答える 5

2

あなたの質問を正しく理解できれば、次のようなものを使用する必要があると思います。

SELECT t1.id, t1.data data_curr, t2.data data_prev, t1.data - t2.data data_diff
FROM (
  SELECT t1.id, t1.data, MAX(t2.id) max_id
  FROM
    tablename t1 INNER JOIN tablename t2
    ON t1.name = t2.name
       AND t1.id > t2.id
  WHERE
    t1.name = 'a'
  GROUP BY
    t1.id, t1.data
) t1 INNER JOIN tablename t2
  ON t1.max_id = t2.id

ここでフィドルを参照してください。これは標準 SQL であり、どの DBMS でも機能するはずです。

ただし、データの LAST diff だけが必要な場合はLIMIT 1、メイン クエリで (ID DESC による順序付け) を使用して、name='a' の最後のデータを取得し、最後LIMIT 1,1から 2 番目のデータを取得できます。

SELECT   id, data data_curr,
         data -
         (SELECT data FROM tablename WHERE name='a' ORDER BY id DESC LIMIT 1,1) data_diff
FROM     tablename
WHERE    name='a'
ORDER BY id DESC
LIMIT 1

こちらを ご覧 ください.

于 2013-03-29T17:25:56.530 に答える
2

どうぞ:

SELECT id, data, data - COALESCE(previous, data) as diff FROM (
SELECT
t.*,
@prev AS previous,
@prev:=t.data 
FROM
tablename t
, (SELECT @prev:=NULL) var
where name = 'a'
)sq
order by diff desc
limit 1

説明:

, (SELECT @prev:=NULL) var

変数の初期化。

@prev AS previous,
@prev:=t.data 

最初の列に変数の現在の値を出力し、2 番目の列に現在の行の値を代入します。

COALESCE(previous, data)

previous がNULLの場合、列データの値を返します。したがって、前の行がない行の差分はゼロです。

ご不明な点がございましたら、お気軽にお問い合わせください。

PS: このクエリは、自己結合が必要なクエリよりも高速になる可能性があります。

于 2013-03-27T16:53:55.813 に答える
1

あなたのデータを考えると、データフィールドの値が上昇しているようで、差は常に正の値になります

これはうまくいくはずです

SELECT 
  id, 
  max(data)-min(data) as diff,
  max(data) as data
  name
FROM
  (
    SELECT
      id,
      data,
      name 
    FROM 
      tablename 
    WHERE 
      name = 'a' 
    ORDER BY
      id desc 
    LIMIT 2 
  ) t
GROUP BY 
  name

SQLFiddleデモ

于 2013-04-01T18:00:54.050 に答える
0

これは良い習慣ではありませんが、私は時々このように半結合に参加します

SELECT
  t1.id,
  t1.data,
  t1.data- t3.data AS diff
FROM tablename t1
  LEFT JOIN tablename t2
    ON t1.id = t2.id
  LEFT JOIN tablename t3
    ON t3.data = (SELECT
            data
          FROM tablename
          WHERE id > t1.id
          LIMIT 1)
ORDER BY diff DESC
LIMIT 1;
于 2013-03-18T11:18:22.207 に答える