PostgreSQL:检测结果集的第一行/最后一行 [英] PostgreSQL: detecting the first/last rows of result set

查看:24
本文介绍了PostgreSQL:检测结果集的第一行/最后一行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆