查找当前行是不是是要从数据库中选择的最后一行

Posted

技术标签:

【中文标题】查找当前行是不是是要从数据库中选择的最后一行【英文标题】:Finding if current row is last row to be selected from database查找当前行是否是要从数据库中选择的最后一行 【发布时间】:2014-03-24 13:08:47 【问题描述】:

我正在从数据库中选择期间列表。如果当前行是第一行,则周期以日期开始,我可以像这样找到周期开始之间的间隔:

SELECT
...
CASE WHEN row_number() OVER(ORDER BY r.created_at ASC) = 1 THEN r.created_at - r.created_at::date ELSE NULL END AS period
...
FROM mytable r

我怎样才能对 last 行执行相同的操作? 查找最后一行的 r.created_at 与其日期的午夜之间的时间。

我知道 PostgreSQL 中的 firstlast 函数 (https://wiki.postgresql.org/wiki/First/last_(aggregate)),但它们是聚合函数,在这种情况下没有帮助。

编辑: 这个问题有2个很好的答案。在我的情况下,它们都没有帮助,因为我作为问题的一部分提出的这一行是更大查询的一部分,以编程方式放在一起并使用提供的解决方案会迫使我更改很多代码,我不愿意这样做这点。如果缩放问题出现 - 那么我一定会重新考虑。

【问题讨论】:

DESC而不是ASC做同样的事情怎么样? 如果您按 (... DESC) 排序,最后一行将是第一行 ... 嗯,这可能真的有效。谢谢。我现在必须测试它:) 你需要created_at排序的结果吗? 谢谢 - 使用 DESC 而不是 ASC 效果很好。 【参考方案1】:

这可能比窗口函数更快:

with r as (
    select
        min(created_at) as min_created_at,
        max(created_at) as max_created_at
    from mytable
)
select
    case when (select min_created_at from r) = created_at
    then created_at - created_at::date else null
    end as period_min,
    case when (select max_created_at from r) = created_at
    then created_at - created_at::date else null
    end as period_max
from mytable

【讨论】:

【参考方案2】:

您可以在单个 CASE 语句中使用window functions first_value() and last_value()

SELECT *
     , CASE WHEN ts IN ( first_value(created_at) OVER w
                       , last_value(created_at)  OVER w)
       THEN created_at::time::interval ELSE NULL END AS period
FROM   tbl
WINDOW w AS (ORDER BY created_at rows BETWEEN UNBOUNDED PRECEDING
                                          AND UNBOUNDED FOLLOWING);

这里的特殊要求:您需要为last_value() 调用调整frame definition。默认是:

RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

但你需要:

ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

first_value() 调用可以使用默认框架,但也可以使用相同的框架。

我还简化了period 的计算。您的定义与 timestamp.time 组件一致,只需转换为 time 以“截断”日期部分:created_at::time。 之后转换为 interval 只是为了返回与原始查询相同的数据类型。

由于当前窗口函数的实现,结果将自动按created_at 排序。但不要依赖于此。如果您需要排序输出,请显式添加到末尾:

ORDER BY created_at

【讨论】:

以上是关于查找当前行是不是是要从数据库中选择的最后一行的主要内容,如果未能解决你的问题,请参考以下文章

excel查找首行某个数值,返回这一列的数据。就是要从一堆数据里找出想要的那列

vim 查找替换

为什么Sqlite只返回最后一行而不是所有行数据?

viim命令行模式查找替换

sql select语句,如何查找最后一行的数据

vim查找/替换字符串