+-------+----------------------+----------+------------------+
| 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的每个唯一组合找到最近的(仅在之前)记录。
因此,如果我查看的是时间戳为“12/1/2015 7:00”的“555”,我应该返回:
+-------+----------------------+----------+------------------+
| 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这样做。

最佳答案

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。详细说明:
Select first row in each GROUP BY group?
根据基数和值频率,可能有更快的查询样式:
Optimize GROUP BY query to retrieve latest record per user
不管怎样,对于非平凡大小的表,amulticolumn indexonNULLS LAST是使其快速运行的关键。排序顺序应该与查询匹配(或者完全反转)。如果将(isbn, book_container_id, update_time DESC)添加到查询中,也可以将其添加到索引中。
旁白:最好对所有日期/时间常量使用ISO8601格式,因为这对于任何语言环境或日期样式设置都是明确的。相关:
PostgreSQL: between with datetime

关于sql - 查询以获取时间戳值最接近的记录以获取两列的唯一组合,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34052157/

10-13 07:45
查看更多