【发布时间】:2016-07-15 22:11:32
【问题描述】:
我有一个表格,其中包含可按多个属性进行逻辑分组的数据(例如外键)。数据在连续时间间隔上是连续的;即它是一个时间序列数据。我想要实现的是只为每组组选择最新的值。
这是示例数据:
+-----------------------------------------+
| code | value | date | relation_id |
+-----------------------------------------+
| A | 1 | 01.01.2016 | 1 |
| A | 2 | 02.01.2016 | 1 |
| A | 3 | 03.01.2016 | 1 |
| A | 4 | 01.01.2016 | 2 |
| A | 5 | 02.01.2016 | 2 |
| A | 6 | 03.01.2016 | 2 |
| B | 1 | 01.01.2016 | 1 |
| B | 2 | 02.01.2016 | 1 |
| B | 3 | 03.01.2016 | 1 |
| B | 4 | 01.01.2016 | 2 |
| B | 5 | 02.01.2016 | 2 |
| B | 6 | 03.01.2016 | 2 |
+-----------------------------------------+
这是所需输出的示例:
+-----------------------------------------+
| code | value | date | relation_id |
+-----------------------------------------+
| A | 3 | 03.01.2016 | 1 |
| A | 6 | 03.01.2016 | 2 |
| B | 3 | 03.01.2016 | 1 |
| B | 6 | 03.01.2016 | 2 |
+-----------------------------------------+
为了正确看待这一点——对于每个相关的对象,我想选择每个具有最新日期的代码。
这是我带来的一个选择。我使用了ROW_NUMBER OVER (PARTITION BY...) 方法:
SELECT indicators.code, indicators.dimension, indicators.unit, x.value, x.date, x.ticker, x.name
FROM (
SELECT
ROW_NUMBER() OVER (PARTITION BY indicator_id ORDER BY date DESC) AS r,
t.indicator_id, t.value, t.date, t.company_id, companies.sic_id,
companies.ticker, companies.name
FROM fundamentals t
INNER JOIN companies on companies.id = t.company_id
WHERE companies.sic_id = 89
) x
INNER JOIN indicators on indicators.id = x.indicator_id
WHERE x.r <= (SELECT count(*) FROM companies where sic_id = 89)
它有效,但问题是它非常缓慢;当使用大约 5% 的生产数据(大约等于 300 万条fundamentals 记录)时,此选择大约需要 10 秒才能完成。我的猜测是由于子选择首先选择了大量记录而发生这种情况。
有什么方法可以加快这个查询速度,还是我在错误的方向上试图按照我的方式进行?
【问题讨论】:
标签: sql postgresql greatest-n-per-group