Introduction to Window Functions in SQL
21–30 of 47 posts
Re: Introduction to Window Functions in SQL
#22Re: Introduction to Window Functions in SQL
#23I 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!
Re: Introduction to Window Functions in SQL
#24If you want to know the highest salary in each department, that's easy:
select department, max(gross_salary)
from salary
group by department
If you want to know who it is who earns that salary, you might try to do this: select department, first_name, max(gross_salary)
from salary
group by department
But this doesn't work, because it's meaningless to ask for first_name in a situation where you're grouping by department. You could ask for an aggregation of all names, but there'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.Window functions let you re-frame this kind of group by like this:
select department, gross_salary
from (
select *, row_number() over (partition by department order by gross_salary desc) as n
from salary
) _
where n = 1
Because the outer query is no longer a group by, you can select any columns you like. The natural query works fine: 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
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.Re: Introduction to Window Functions in SQL
#25A few cool tricks I use with window functions: 1- To find blocks of contiguous values, you can use something similar to Gauss' 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/min and get rows that correspond to the blocks of values. select min(n), max(n) from ( select n, n+row_n…
It's been some time since I've done serious work with SQL yet I remember that all paging solutions I've found (eg. top results on SO) are always platform-specific so having a platform-independent way of doing it would mean I could finally try to remember it.
Re: Introduction to Window Functions in SQL
#26 SELECT
tm.*
FROM
(
SELECT
row_number() OVER (
PARTITION BY tm_1.thread_id
ORDER BY tm_1.delivered_at DESC
) AS "row",
tm_1.*
FROM
thread_message tm_1
) tm
WHERE
tm."row" = 1;
The inner query groups all messages by thread, orders them to find the "most recent" 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.Re: Introduction to Window Functions in SQL
#27What i like most about window functions is that they give me a way to do a sort of 'extended group by' which i have always wanted. If you want to know the highest salary in each department, that's easy: select department, max(gross_salary) from salary group by department If you want to know who it is who earns that salary, you might try to do this: select department, first_name, max(gross_salary) from salary group by…
Well, there is a way which is window functions :) as shown by you.
The idea to expect exactly one first name of the person with the biggest salary is kinda wrong, since there can be more than one person, and this can obviously not described as a single column per group.
Note that aggregating is not limited to min, max, sum, etc. Postgres, for example, has array_agg which aggregates individual columns from each record of a group into an array, if that becomes necessary.
Re: Introduction to Window Functions in SQL
#28The 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.
It may be the difference between correcting a few lines, vs reworking 20+ different queries, and testing each one individually.
Re: Introduction to Window Functions in SQL
#29A few cool tricks I use with window functions: 1- To find blocks of contiguous values, you can use something similar to Gauss' 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/min and get rows that correspond to the blocks of values. select min(n), max(n) from ( select n, n+row_n…
Could you please develop how to do paging with window functions? It's been some time since I've done serious work with SQL yet I remember that all paging solutions I've found (eg. top results on SO) are always platform-specific so having a platform-independent way of doing it would mean I could finally try to remember it.
As in: SELECT * FROM (SELECT *, row_number() OVER (order by ) as rowidx FROM your_table) as numbered WHERE rowidx > ? AND rowid < ?
Re: Introduction to Window Functions in SQL
#30Favorite/weirdest thing I learned to do most recently with window functions is using/abusing min() and max(). If there is no value in a column in a particular window, min and max will give NULL.
We use this to do really interesting stuff (entirely in sql!) like "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"