PostgreSQL:检测结果集的第一行/最后一行 [英] PostgreSQL: detecting the first/last rows of result set
问题描述
有没有办法在SELECT中嵌入指示它是结果集的第一行或最后一行的标志?我在想一些事情的影响:
> SELECT is_first_row() AS f, is_last_row() AS l FROM blah;
f | l
-----------
t | f
f | f
f | f
f | f
f | t
答案可能在window functions中,但我才刚刚了解它们,我质疑它们的效率。
SELECT first_value(unique_column) OVER () = unique_column, last_value(unique_column) OVER () = unique_column, * FROM blah;
似乎做了我想做的事。不幸的是,我甚至不能完全理解这种语法,但由于unique_column
是唯一的,并且NOT NULL
应该会产生明确的结果。但如果它确实进行了分类,那么治愈方法可能比疾病更糟糕。(实际上,在我的测试中,unique_column
未对进行排序,所以这不算什么。)
EXPLAIN ANALYZE
并不表示效率有问题,但它什么时候告诉过我需要知道的信息?
我可能需要在聚合函数中使用它,但我刚刚被告知窗口函数在那里是不允许的。😕
编辑:
实际上,我只是在上面的查询中添加了ORDER BY unique_column
,标识为第一行和最后一行的行被抛到结果集的中间。这就好像first_value()
/last_value()
实际上意味着"我在开始排序之前拾取的第一个/最后一个值"。我认为我不能安全地以最佳方式做到这一点。除非要更好地了解OVER
关键字的用法。
我在Debian 9.5环境中运行PostgreSQL 9.6。
这不是重复的,因为我正在尝试获取结果集的第一行和最后一行来标识自己,而Postgres: get min, max, aggregate values in one select只是获取结果集中某列的最小值和最大值。
推荐答案
使用窗口函数非常简单frames:
with t(x, y) as (select generate_series(1,5), random())
select *,
count(*) over (rows between unbounded preceding and current row),
count(*) over (rows between current row and unbounded following)
from t;
┌───┬───────────────────┬───────┬───────┐
│ x │ y │ count │ count │
├───┼───────────────────┼───────┼───────┤
│ 1 │ 0.543995119165629 │ 1 │ 5 │
│ 2 │ 0.886343683116138 │ 2 │ 4 │
│ 3 │ 0.124682310037315 │ 3 │ 3 │
│ 4 │ 0.668972567655146 │ 4 │ 2 │
│ 5 │ 0.266671542543918 │ 5 │ 1 │
└───┴───────────────────┴───────┴───────┘
如您所见,count(*) over (rows between unbounded preceding and current row)
返回从数据集开始到当前行的行数,count(*) over (rows between current row and unbounded following)
返回从当前行到数据集结束的行数。1
表示第一行/最后一行。
order by
对您的数据集进行排序之前,它一直有效。在这种情况下,您需要在框架定义中复制它:
with t(x, y) as (select generate_series(1,5), random())
select *,
count(*) over (order by y rows between unbounded preceding and current row),
count(*) over (order by y rows between current row and unbounded following)
from t order by y;
┌───┬───────────────────┬───────┬───────┐
│ x │ y │ count │ count │
├───┼───────────────────┼───────┼───────┤
│ 1 │ 0.125781774986535 │ 1 │ 5 │
│ 4 │ 0.25046408502385 │ 2 │ 4 │
│ 5 │ 0.538880597334355 │ 3 │ 3 │
│ 3 │ 0.802807193249464 │ 4 │ 2 │
│ 2 │ 0.869908029679209 │ 5 │ 1 │
└───┴───────────────────┴───────┴───────┘
ps:如comment中的a_horse_with_no_name所述:
没有排序就没有"第一行"或"最后一行"。
这篇关于PostgreSQL:检测结果集的第一行/最后一行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!