TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Introduction to Window Functions in SQL

196 点作者 adilkhash超过 4 年前

15 条评论

forinti超过 4 年前
A few cool tricks I use with window functions:<p>1- To find blocks of contiguous values, you can use something similar to Gauss&#x27; trick for calculating arithmetic progressions: sort them by descending order and add each value to the row number. All contiguous values will add to the same number. You can then apply max&#x2F;min and get rows that correspond to the blocks of values.<p><pre><code> select min(n), max(n) from ( select n, n+row_number() over (order by n desc) group from numbers ) group by group order by 1 </code></pre> 2- You can use a window function with exponential&#x2F;logarithms in order to calculate the accumulated inflation for the last n months:<p><pre><code> select date, inflation, (exp(accumulated)-1)*100 from ( select date, inflation, sum(ln(1+(inflation&#x2F;100))) over (order by date desc rows between current row and 11 following) as accumulated from inflation ) </code></pre> 3- You can do all the paging in SQL (fetch page n of m) or simply add a column with the total number of rows (this often makes it easier to process the results).
评论 #25657588 未加载
throw_m239339超过 4 年前
Introduction to Window Functions with the same examples (salaries per department)<p><a href="https:&#x2F;&#x2F;www.postgresql.org&#x2F;docs&#x2F;13&#x2F;tutorial-window.html" rel="nofollow">https:&#x2F;&#x2F;www.postgresql.org&#x2F;docs&#x2F;13&#x2F;tutorial-window.html</a><p>While you are at it, check out common table expressions as well<p><a href="https:&#x2F;&#x2F;www.postgresql.org&#x2F;docs&#x2F;13&#x2F;queries-with.html" rel="nofollow">https:&#x2F;&#x2F;www.postgresql.org&#x2F;docs&#x2F;13&#x2F;queries-with.html</a>
评论 #25656774 未加载
dmitryminkovsky超过 4 年前
I&#x27;ve been working on a messaging app, and at the beginning I started out with Elasticsearch. Now, ES is really a wonderful tool and it got me pretty far, but its lack of window functions made one particular requirement impossible that we all take for granted in messengers: a listing of most-recently updated threads represented by the most recent message on each thread, sorted reverse chronologically. Here is the SQL that makes that happen:<p><pre><code> SELECT tm.* FROM ( SELECT row_number() OVER ( PARTITION BY tm_1.thread_id ORDER BY tm_1.delivered_at DESC ) AS &quot;row&quot;, tm_1.* FROM thread_message tm_1 ) tm WHERE tm.&quot;row&quot; = 1; </code></pre> The inner query groups all messages by thread, orders them to find the &quot;most recent&quot; message on a thread given my ordering requirements, and then assigns a row number to each such message such that I can pick the most recent message on each thread in the outside query. I still have no idea how I would have done this with Elasticsearch.
davidhyde超过 4 年前
I find window functions to be an excellent way to find the max version of a set of things. The trick is to partition by some columns (similar to how you would use a group by), order by descending on your version number field, and use the row_number() function which is very lightweight. Then you filter for all entries where rownumber = 1 and voila you have the max version without having to link back on yourself!
评论 #25659948 未加载
评论 #25667860 未加载
评论 #25657290 未加载
fronofro超过 4 年前
I made gifs to explain the different types of window functions: <a href="https:&#x2F;&#x2F;dataschool.com&#x2F;how-to-teach-people-sql&#x2F;how-window-functions-work&#x2F;" rel="nofollow">https:&#x2F;&#x2F;dataschool.com&#x2F;how-to-teach-people-sql&#x2F;how-window-fu...</a>
twic超过 4 年前
What i like most about window functions is that they give me a way to do a sort of &#x27;extended group by&#x27; which i have always wanted.<p>If you want to know the highest salary in each department, that&#x27;s easy:<p><pre><code> select department, max(gross_salary) from salary group by department </code></pre> If you want to know who it is who earns that salary, you might try to do this:<p><pre><code> select department, first_name, max(gross_salary) from salary group by department </code></pre> But this doesn&#x27;t work, because it&#x27;s meaningless to ask for first_name in a situation where you&#x27;re grouping by department. You could ask for an aggregation of all names, but there&#x27;s no straightforward way to ask for the name of the person who earned that salary. You end up having to write a join against the group by, as in the article, which is pretty grim, and falls apart if you want to order by multiple columns to break ties.<p>Window functions let you re-frame this kind of group by like this:<p><pre><code> select department, gross_salary from ( select *, row_number() over (partition by department order by gross_salary desc) as n from salary ) _ where n = 1 </code></pre> Because the outer query is no longer a group by, you can select any columns you like. The natural query works fine:<p><pre><code> select department, first_name, gross_salary from ( select *, row_number() over (partition by department order by gross_salary desc) as n from salary ) _ where n = 1 </code></pre> This only works where the group by is based on an aggregate function that picks one value, like min or max. I somewhat think it was a mistake to model that kind of thing as an aggregation in the first place. If SQL had a way of picking one row from a group, rather than aggregating over it, that would be immensely useful.
评论 #25660229 未加载
评论 #25657666 未加载
评论 #25672188 未加载
评论 #25669262 未加载
n4r9超过 4 年前
I like how the article teaches by explicit example. Very helpful when it comes to data.<p>The &quot;lag&quot; and &quot;lead&quot; SQL functions are particularly useful when analysing sequences of timestamped events (GPS fixes, task completions etc). They allow you to easily return the delta of a value (time&#x2F;distance) between the current and previous row, which is really useful if you want to compare expected vs actual on those deltas.
llampx超过 4 年前
Question for the pros: In doing some data engineering work, I found that creating temporary tables and dropping them after the run was much more performant and memory-efficient than using CTEs. No other change was made to the queries in the CTE, just putting them in a separate CREATE TABLE AS... script before the part that needed the calculations.<p>Why is this the case? Shouldn&#x27;t CTEs be more efficient?
评论 #25657277 未加载
评论 #25658956 未加载
评论 #25659343 未加载
stelliosk超过 4 年前
Analytic functions as they are known by in Oracle, SQL have been around for more than a decade. They are useful for calculating running balances, getting a previous or next row value, doing a &quot;group by&quot; for a subset of columns.. etc. They&#x27;re the best thing in SQL &quot;since sliced bread&quot;.<p><a href="https:&#x2F;&#x2F;towardsdatascience.com&#x2F;analytical-functions-in-oracle-4ac48e022370" rel="nofollow">https:&#x2F;&#x2F;towardsdatascience.com&#x2F;analytical-functions-in-oracl...</a>
hospadar超过 4 年前
Wow I love me a window function!<p>Favorite&#x2F;weirdest thing I learned to do most recently with window functions is using&#x2F;abusing min() and max(). If there is no value in a column in a particular window, min and max will give NULL.<p>We use this to do really interesting stuff (entirely in sql!) like &quot;partition usage into sessions where a session is defined as a bunch of activity by a user where they did an action at least once every 30 minutes&quot;
评论 #25657912 未加载
llampx超过 4 年前
Previous discussion on SQL Window functions: <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=20872114" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=20872114</a><p>Helpful resource: <a href="http:&#x2F;&#x2F;www.windowfunctions.com&#x2F;" rel="nofollow">http:&#x2F;&#x2F;www.windowfunctions.com&#x2F;</a>
评论 #25656830 未加载
extrememacaroni超过 4 年前
SQL is only secondary in my work but I&#x27;d rather go with the explicit and verbose queries rather than with stuff with surprises like how the last_value gives wrong results when used the way you&#x27;d expect i.e. the reverse of first_value.
评论 #25657970 未加载
morrbo超过 4 年前
I&#x27;ve always wondered and perhaps someone here might know....do postgres&#x27; CTEs translate into big select&#x2F;sub select queries under the hood? Or are they something special entirely? Ie (forgive formatting as I&#x27;m on phone) does:<p>With mything as ( Select * from table where... ),<p>Myotherthing as ( Select * from mything where... )<p>Get translated to<p>Select * from (select * from ( select * from...)...)...)<p>So I&#x27;m just wondering are CTEs just easier to read, or do they offer any other known optimizations? We use them loads but mainly just for keeping larger queries easier to manage
评论 #25656866 未加载
评论 #25656859 未加载
评论 #25656839 未加载
Strs2FillMyDrms超过 4 年前
I&#x27;ve been encountering a lot of issues, when doing dedicated queries, specially when a team is small, I&#x27;ve found is sometimes more useful to just do the grouping or left join (if more than 2 are required) manually.<p>The problem is ofc scalability, if your team is small it is better to just have some few, but very specific queries, and do whatever transactions required on a layer above.<p>It may be the difference between correcting a few lines, vs reworking 20+ different queries, and testing each one individually.
kartaevt超过 4 年前
Finally, comprehensive article about Windows Functions.
评论 #25656828 未加载