我有一个表格,其中包含日期列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中完成,而不需要涉及任何脚本语言。
答案 0 :(得分: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
第二种方法使用三角形自连接以及反自我连接。基本上,它可以这样翻译:
将每一行与每个前一个行与相同的
id
(第一个外连接,三角连接)组合,然后去除前一个部分不代表最新前一个的每一行(第二个外连接+WHERE
中的条件,或反连接。
答案 1 :(得分: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;
或许解决方案可能类似。 这是一个id。您可能需要为每个此类ID循环代码。