从表中获取最小和最大行

Roc*_*nja 0 postgresql postgresql-9.4

从带有列的表中: id(pk), type_id, book_id, title_id, page_id, lines(int4), created_at(date)

如何选择带有min(lines)max(lines)for (type_id, book_id, title_id, page_id) 的行以及created_atwhen min(lines) 的值和最大值的值。

虚拟数据:

type_id, book_id, title_id, page_id, lines, created_at
1, 1, 1, 1, 12, 2015-04-01
1, 1, 1, 1, 10, 2015-03-01
1, 1, 1, 1, 11, 2015-03-02
1, 1, 1, 2, 3, 2015-04-01
1, 1, 1, 2, 5, 2015-03-01
1, 1, 1, 2, 6, 2015-03-04
Run Code Online (Sandbox Code Playgroud)

预期输出:

type_id, book_id, title_id, page_id, min, min_created_at, max, max_created_at
1, 1, 1, 1, 10, 2015-03-01, 11, 2015-03-02
1, 1, 1, 2, 3, 2015-04-01, 6, 2015-03-04
Run Code Online (Sandbox Code Playgroud)

ype*_*eᵀᴹ 5

一种方法是使用窗口函数:

SELECT DISTINCT
    type_id, book_id, title_id, page_id,
    first_value(lines)      OVER wmin AS min_lines, 
    first_value(created_at) OVER wmin AS min_created_at, 
    first_value(lines)      OVER wmax AS max_lines,
    first_value(created_at) OVER wmax AS max_created_at
FROM 
    tableX
WINDOW 
    wmin AS (PARTITION BY type_id, book_id, title_id, page_id 
             ORDER BY lines ASC, created_at ASC), 
    wmax AS (PARTITION BY type_id, book_id, title_id, page_id 
             ORDER BY lines DESC, created_at ASC) ;
Run Code Online (Sandbox Code Playgroud)

SQLfiddle测试。