From: | Andreas Kretschmer <andreas(at)a-kretschmer(dot)de> |
---|---|
To: | pgsql-general(at)postgresql(dot)org |
Subject: | Re: Ordering of window functions with no order specified? |
Date: | 2017-06-15 05:26:57 |
Message-ID: | cc8431b9-7805-9e34-ad8b-4dced9d422eb@a-kretschmer.de |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
Am 15.06.2017 um 06:34 schrieb Ken Tanzer:
> Hi. If you use a window function and don't specify an order, will the
> rows be processed in the same order as the query results?
>
> In this particular case, I'm wondering about row_number(), and whether
> I explicitly need to repeat the ordering that's already specified in
> the query?
>
> SELECT a,b,c,row_number()
> OVER (PARTITION BY a) -- Do I need an ORDER BY c,b here?
> FROM foo
> ORDER BY c,b
>
> Also, I'm interested in both what if any behavior is guaranteed, and
> what gets done in practice. (i.e., a SELECT with no order doesn't
> have guarantees, but in practice seems to return the results in the
> order they were added to the table. Is it something similar here?)
>
That's different queries and results:
test=# create table foo as select s%5 a, random() as b, random() as c
from generate_series(1, 20) s;
SELECT 20
test=*# select a, b, c, row_number() over (partition by a) from foo
order by c,b;
a | b | c | row_number
---+--------------------+---------------------+------------
3 | 0.293813084252179 | 0.00748801836743951 | 4
2 | 0.366433540824801 | 0.0825160844251513 | 3
2 | 0.646373085677624 | 0.144253523554653 | 2
1 | 0.436142998747528 | 0.149559560697526 | 4
4 | 0.766950330231339 | 0.279563031159341 | 2
4 | 0.780563669744879 | 0.36753943329677 | 4
4 | 0.521357014775276 | 0.37830171873793 | 1
3 | 0.641054477542639 | 0.438840930350125 | 3
0 | 0.23528463486582 | 0.506252389866859 | 1
1 | 0.883372921962291 | 0.607358017936349 | 2
2 | 0.0624627070501447 | 0.610814236104488 | 4
1 | 0.203920441213995 | 0.680096843745559 | 3
0 | 0.945639119483531 | 0.686336697079241 | 3
2 | 0.360363553743809 | 0.702507333364338 | 1
0 | 0.493005351629108 | 0.739280233159661 | 4
0 | 0.844849191140383 | 0.756641649641097 | 2
1 | 0.375874035060406 | 0.771526555530727 | 1
4 | 0.0844886344857514 | 0.837361172772944 | 3
3 | 0.50597962597385 | 0.841444775927812 | 2
3 | 0.0100470245815814 | 0.899044481106102 | 1
(20 Zeilen)
test=*# select a, b, c, row_number() over (partition by a order by c,b)
from foo order by c,b;
a | b | c | row_number
---+--------------------+---------------------+------------
3 | 0.293813084252179 | 0.00748801836743951 | 1
2 | 0.366433540824801 | 0.0825160844251513 | 1
2 | 0.646373085677624 | 0.144253523554653 | 2
1 | 0.436142998747528 | 0.149559560697526 | 1
4 | 0.766950330231339 | 0.279563031159341 | 1
4 | 0.780563669744879 | 0.36753943329677 | 2
4 | 0.521357014775276 | 0.37830171873793 | 3
3 | 0.641054477542639 | 0.438840930350125 | 2
0 | 0.23528463486582 | 0.506252389866859 | 1
1 | 0.883372921962291 | 0.607358017936349 | 2
2 | 0.0624627070501447 | 0.610814236104488 | 3
1 | 0.203920441213995 | 0.680096843745559 | 3
0 | 0.945639119483531 | 0.686336697079241 | 2
2 | 0.360363553743809 | 0.702507333364338 | 4
0 | 0.493005351629108 | 0.739280233159661 | 3
0 | 0.844849191140383 | 0.756641649641097 | 4
1 | 0.375874035060406 | 0.771526555530727 | 4
4 | 0.0844886344857514 | 0.837361172772944 | 4
3 | 0.50597962597385 | 0.841444775927812 | 3
3 | 0.0100470245815814 | 0.899044481106102 | 4
(20 Zeilen)
And also different execution plans:
test=*# explain analyse select a, b, c, row_number() over (partition by
a) from foo order by c,b;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------
Sort (cost=239.18..243.43 rows=1700 width=20) (actual
time=0.134..0.138 rows=20 loops=1)
Sort Key: c, b
Sort Method: quicksort Memory: 26kB
-> WindowAgg (cost=118.22..147.97 rows=1700 width=20) (actual
time=0.056..0.101 rows=20 loops=1)
-> Sort (cost=118.22..122.47 rows=1700 width=20) (actual
time=0.048..0.054 rows=20 loops=1)
Sort Key: a
Sort Method: quicksort Memory: 26kB
-> Seq Scan on foo (cost=0.00..27.00 rows=1700
width=20) (actual time=0.021..0.028 rows=20 loops=1)
Planning time: 0.104 ms
Execution time: 0.200 ms
(10 Zeilen)
test=*# explain analyse select a, b, c, row_number() over (partition by
a order by c,b) from foo order by c,b;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------
Sort (cost=247.68..251.93 rows=1700 width=20) (actual
time=0.115..0.119 rows=20 loops=1)
Sort Key: c, b
Sort Method: quicksort Memory: 26kB
-> WindowAgg (cost=118.22..156.47 rows=1700 width=20) (actual
time=0.056..0.090 rows=20 loops=1)
-> Sort (cost=118.22..122.47 rows=1700 width=20) (actual
time=0.048..0.054 rows=20 loops=1)
Sort Key: a, c, b
Sort Method: quicksort Memory: 26kB
-> Seq Scan on foo (cost=0.00..27.00 rows=1700
width=20) (actual time=0.019..0.025 rows=20 loops=1)
Planning time: 0.100 ms
Execution time: 0.173 ms
(10 Zeilen)
As you can see, different sort keys for the WindowAgg-Sort.
Please don't mix the ORDER BY for the window-function and for the
result-set. Use alwyas an explicit ORDER BY if you expect an ordered result.
Regards, Andreas
--
2ndQuadrant - The PostgreSQL Support Company.
www.2ndQuadrant.com
From | Date | Subject | |
---|---|---|---|
Next Message | David G. Johnston | 2017-06-15 05:27:19 | Re: Ordering of window functions with no order specified? |
Previous Message | Ken Tanzer | 2017-06-15 04:34:33 | Ordering of window functions with no order specified? |