【发布时间】:2019-02-06 15:28:42
【问题描述】:
有没有办法在选择中嵌入一个标志,表明它是结果集的第一行或最后一行?我在想一些大意的东西:
> 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 和 last 的行放入结果集的中间。好像first_value()/last_value() 真的意味着“我在开始排序之前拾取的第一个/最后一个值”。我认为我不能安全地以最佳方式做到这一点。除非对 OVER 关键字的使用有更好的理解。
我在 Debian 9.5 环境中运行 PostgreSQL 9.6。
这不是重复的,因为我试图让结果集的第一行和最后一行来标识自己,而 Postgres: get min, max, aggregate values in one select 只是在结果中获取列的最小值和最大值设置。
【问题讨论】:
-
知道第一条和最后一条记录的目的是什么?你想用它进一步做什么?是的,窗口函数是此类问题的最佳解决方案。如果您需要聚合,只需将第一个查询的结果用作聚合查询中的表,然后它就可以正常工作
-
结果集将被异步发送到另一个系统,该系统想知道它正在查看结果集的哪一部分。生成结果集后很难应用这些符号
-
在关系数据库中没有“第一行”或“最后一行”之类的东西。表中的行不以任何方式排序。因此,除非您指定排序定义,否则您无法分辨“第一”行是什么。
-
你有一个 empty 窗口定义:
OVER (),这意味着:一切顺利!。将其与我的答案中的窗口定义进行比较,后者 确实 强加了一个命令。 -
@Opux,说实话,我认为你把事情复杂化了很多。如果您不订购记录,那么第一个和最后一个是完全随机的。更重要的是,当它进入另一个系统时,它可以以与您的语句完全不同的顺序阅读。您将只有 2 条记录被标记为数百、数千或数百万条记录。有用性接近于零,或者我错过了一些非常重要的事情,不明白你为什么要那样做。
标签: postgresql select window-functions