查询以获得具有最接近的时间戳值的记录,以获得两列的唯一组合

时间:2015-12-02 20:14:15

标签: sql postgresql greatest-n-per-group

+-------+----------------------+----------+------------------+
| isbn  | book_container_id    | shelf_id |   update_time    |
+-------+----------------------+----------+------------------+
|   555 |                    6 | shelf100 | 11/15/2015 19:10 |
|   123 |                    1 | shelf1   | 11/28/2015 8:00  |
|   555 |                    4 | shelf5   | 11/28/2015 9:10  |
|   212 |                    2 | shelf2   | 11/29/2015 8:10  |
|   555 |                    6 | shelf9   | 11/30/2015 22:10 |
|   321 |                    8 | shelf7   | 11/30/2015 8:10  |
|   555 |                    4 | shelf33  | 12/1/2015 7:00   |
+-------+----------------------+----------+------------------+

我们说我有一个表(PostgreSQL),就像上面的bookshelf_configuration一样。如果我获得了ISBN和时间戳,我希望能够找到isbnbook_container_id的每个唯一组合的最接近(仅限之前)记录。

因此,如果我正在查看isbn''',时间戳为< 12/1/2015 7:00',我应该回来:

+-------+----------------------+----------+------------------+
| isbn  | book_container_id    | shelf_id |   update_time    |
+-------+----------------------+----------+------------------+
|   555 |                    6 | shelf9   | 11/30/2015 22:10 |
|   555 |                    4 | shelf33  | 12/1/2015 7:00   |
+-------+----------------------+----------+------------------+

我对SQL的了解非常基础。如果我只需要考虑isbn,我会得到一个可行的查询,但我需要一些帮助来了解如何为组合(isbn, book_container_id)执行此操作。

2 个答案:

答案 0 :(得分:2)

有一种名为Select * From ( Select *, row_number() OVER (partition by isbn, book_container_id order by update_time desc) rn From bookshelf_configuration Where isbn = 555 and update_time <= '12/1/2015 7:00' ) q Where q.rn = 1 的东西可以帮到你。

{{1}}

答案 1 :(得分:2)

DISTINCT ON 的典型用例:

SELECT DISTINCT ON (book_container_id)
       isbn, book_container_id, shelf_id, update_time 
FROM   bookshelf_configuration
WHERE  isbn = 555
AND    update_time <= '2015-12-01 07:00'  -- ISO 8601 format
ORDER  BY book_container_id, update_time DESC;

假设update_time已定义NOT NULL,或者您必须添加NULLS LAST。详细解释:

根据基数和值频率,可能会有更快的查询样式:

无论哪种方式,(isbn, book_container_id, update_time DESC)上的multicolumn index是使非平凡大小的表快速运行的关键。排序顺序应该与查询匹配(或者它是完整的反转)。如果您向查询添加NULLS LAST,也可以将其添加到索引中。

除此之外:对所有日期/时间常数使用ISO 8601格式更好,因为这与任何区域设置或日期样式设置都是明确的。相关: