2

dte日付列 、 ID 列 、idおよび値列を含むテーブルがありますval。各 ID には複数の日付が含まれ、各日付には複数の ID が含まれます。これはパネル データ セットです。各 ID について、現在の日付、現在の値、および最後に利用可能な日付 (現在の日付より前) の値を取得したいと考えています。mysqlでこれを行う最良の方法は何ですか? 私のテーブルはそれほど大きくなく (2 ミルのレコード)、妥当な時間内にこれを機能させたいと考えています。

データのサンプルを次に示します。

dte, id, value
2001-01-01, 1, 10
2001-01-02, 1, 20
2001-01-03, 1, 30
2001-01-04, 1, 40
2001-01-01, 2, 100
2001-01-02, 2, 200
2001-01-03, 2, 300
2001-01-05, 2, 400
2001-01-01, 3, 1000
2001-01-02, 3, 2000
2001-01-05, 3, 3000

以下を取得したいと思います。

dte, id, value, previous_value
2001-01-01, 1, 10, NULL
2001-01-02, 1, 20, 10
2001-01-03, 1, 30, 20
2001-01-04, 1, 40, 30
2001-01-01, 2, 100, NULL
2001-01-02, 2, 200, 100
2001-01-03, 2, 300, 200
2001-01-05, 2, 400, 300
2001-01-01, 3, 1000, NULL
2001-01-02, 3, 2000, 1000
2001-01-05, 3, 3000, 2000

これは、スクリプト言語を使用せずに純粋な SQL で実行する必要があります。

4

2 に答える 2

2

「前の」行から 1 列だけが必要なため、次のようなことを試すことができます。

SELECT
  dte,
  id,
  value,
  (
    SELECT value
    FROM atable
    WHERE id = t.id
      AND dte < t.dte
    ORDER BY dte DESC
    LIMIT 1
  ) AS previous_value
FROM atable t

さらに「前の」属性を取得する必要がある場合は、より洗練された方法を次に示します。

SELECT
  t1.dte,
  t1.id,
  t1.value,
  t2.dte,
  t2.value,
  …
FROM atable t1
  LEFT JOIN atable t2 ON t1.id = t2.id AND t1.dte > t2.dte
  LEFT JOIN atable t3 ON t1.id = t3.id AND t1.dte > t3.dte AND t3.dte > t2.dte
WHERE t3.id IS NULL

2 番目のアプローチでは、三角形の自己結合と自己へのアンチ結合を使用します。基本的には、次のように翻訳できます。

すべての行をそのすべての先行要素と同じものid(最初の外部結合、三角結合) と結合し、先行部分が最新の先行要素を表していないすべての行を取り除きます (2 番目の外部結合 + の条件WHERE、またはアンチ結合)。

于 2012-06-30T21:28:20.847 に答える
0

これは機能しますか?

select dte,id,value,(select value as previous_value from sample where id=1 
and dte<(select dte from sample where id=1 order by dte desc limit 1) order by
dte desc limit 1) from sample where id=1;

あるいは、解決策は似たようなものかもしれません。これは1つのID用です。そのような ID ごとにコードをループする必要がある場合があります。

于 2012-06-30T20:18:48.793 に答える