了解窗口函数

发布于 2025-01-17 06:22:02 字数 2623 浏览 3 评论 0原文

Postgres-sql:

我无法找到可以帮助我理解如何正确使用带有/内部窗口函数的聚合以及如何正确使用 RANGE/ROWS frame_clause 的资源。我在网上查看了一些资源,例如: https://www.compose.com/articles/metrics -maven-window-frames-in-postgresql/
(我真的很喜欢这篇文章,它解决了一些疑问)

  1. 在窗口函数中正确使用聚合 总和() 超过(...) 有时会在我最不期望的时候生成多行,或者要求我向 groupby 添加更多列

例如: 对于这里的问题:https://pgexercises.com/questions/aggregates/fachours4.html

select facid, total from
(select facid, sum(slots) total, RANK() OVER (order by sum(slots) desc) pos
from cd.bookings
group by facid
 ) A
where pos = 1

我写了这个查询并且它工作正常。但为此: https://pgexercises.com/questions/aggregates/rollingavg.html,我写了这个查询:

select starttime::date, sum(slots * case when memid=0 then guestcost
                        else membercost end) over (order by starttime::date asc
                                                   range BETWEEN INTERVAL '14 day' 
                                                   PRECEDING AND 
                                                   CURRENT ROW)::decimal/15 revenue
from cd.bookings B inner join cd.facilities F
on B.facid = F.facid
where starttime >= '2012-08-01' and starttime <= '2012-08-31' 
group by starttime::date, slots, memid, guestcost, membercost
order by starttime::date

它要求我将slots、memid、guestcost、membercost添加到groupby中,当它们是平均计算的一部分时。 我还没有正确解决这个问题。

  1. 不同的窗口函数如何与 RANGE/ROWS 一起操作? 例如,rank() 似乎在没有为其指定框架子句 UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING 的情况下产生正确的结果,但对于此处的 last_value() 计算,需要指定此子句
SELECT
    product_name,
    group_name,
    price,
    LAST_VALUE (price) OVER (
        PARTITION BY group_name
        ORDER BY
            price RANGE BETWEEN UNBOUNDED PRECEDING
        AND UNBOUNDED FOLLOWING
    ) AS highest_price_per_group
FROM
    products
INNER JOIN product_groups USING (group_id);

:(这个例子取自这里: https://www.postgresqltutorial.com/postgresql-window-function/ - 抱歉,无法在页面中选择要链接到此处的确切区域)

vs

SELECT
    RANK () OVER ( 
        ORDER BY price
    ) rank_number 
FROM
    sales;

->;无需指定 BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING 子句即可正确排名。

Postgres-sql:

I'm not able to find a resource which can help me understand how to correctly use aggregates with/inside window functions and how to use RANGE/ROWS frame_clause correctly. I have reviewed some resources online, like:
https://www.compose.com/articles/metrics-maven-window-frames-in-postgresql/
(I really liked the article, it solved some doubts)

  1. Using aggregates correctly with/inside window functions
    SUM() OVER(... )
    sometimes produces multiple rows when I'm least expecting them, or asks me to add more columns to groupby

For example:
For the question here: https://pgexercises.com/questions/aggregates/fachours4.html

select facid, total from
(select facid, sum(slots) total, RANK() OVER (order by sum(slots) desc) pos
from cd.bookings
group by facid
 ) A
where pos = 1

I wrote this query and it works correctly. But for this: https://pgexercises.com/questions/aggregates/rollingavg.html, I wrote this query:

select starttime::date, sum(slots * case when memid=0 then guestcost
                        else membercost end) over (order by starttime::date asc
                                                   range BETWEEN INTERVAL '14 day' 
                                                   PRECEDING AND 
                                                   CURRENT ROW)::decimal/15 revenue
from cd.bookings B inner join cd.facilities F
on B.facid = F.facid
where starttime >= '2012-08-01' and starttime <= '2012-08-31' 
group by starttime::date, slots, memid, guestcost, membercost
order by starttime::date

and it asks me to add slots, memid, guestcost, membercost to the groupby when they are a part of the average calculation.
I haven't correctly solved this question yet.

  1. How do different window functions operate with RANGE/ROWS?
    For example, rank() seems to produce correct results without frame clause UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING being specified for it, but for the last_value() calculation here, there is a need to specify this clause:
SELECT
    product_name,
    group_name,
    price,
    LAST_VALUE (price) OVER (
        PARTITION BY group_name
        ORDER BY
            price RANGE BETWEEN UNBOUNDED PRECEDING
        AND UNBOUNDED FOLLOWING
    ) AS highest_price_per_group
FROM
    products
INNER JOIN product_groups USING (group_id);

(this example is taken from here: https://www.postgresqltutorial.com/postgresql-window-function/ - sorry, not able to select the exact area in the page to link here)

vs

SELECT
    RANK () OVER ( 
        ORDER BY price
    ) rank_number 
FROM
    sales;

-> this ranks correctly without needing to specify the BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING clause.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

垂暮老矣 2025-01-24 06:22:02

https://momjian.us/main/writings/pgsql/window.pdf(幻灯片 35 和幻灯片 36)
https://modern-sql.com/caniuse/over_range_ Between_(numeric)< br>
我希望下面的图片可以帮助您理解over rowsover range之间的区别。
输入图片此处描述

https://momjian.us/main/writings/pgsql/window.pdf (slide 35 and slide 36)
https://modern-sql.com/caniuse/over_range_between_(numeric)
I hope the following picture can help you understand the difference between over rows versus over range.
enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文