2

我有一个表,其中包含一个日期列 、dte一个 id 列id和一个值列val。每个 id 包含多个日期,每个日期包含多个 id:这是一个面板数据集。我想检索每个 id 的当前日期、当前值和上一个可用日期(当前日期之前)的值。在 mysql 中执行此操作的最佳方法是什么?我的表不是很大(200 万条记录),我希望它能够在合理的时间内工作。

以下是数据示例:

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

由于您只需要“上一个”行中的一列,您可以尝试以下操作:

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

第二种方法使用三角形自连接以及反连接到自身。基本上可以这样翻译:

将每一行与它的每个前任组合在一起id(第一个外连接,三角连接),然后去掉前任部分不代表最新前任的每一行(第二个外连接 + 中的条件WHERE,或反加入)。

于 2012-06-30T21:28:20.847 回答
0

Does this work?

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;

Or maybe the solution might be something similar. This is for one id. You might have to loop the code for each such id.

于 2012-06-30T20:18:48.793 回答