Re: [GENERAL] Ordering of window functions with no order specified? - Mailing list pgsql-general

From Andreas Kretschmer
Subject Re: [GENERAL] Ordering of window functions with no order specified?
Date
Msg-id cc8431b9-7805-9e34-ad8b-4dced9d422eb@a-kretschmer.de
Whole thread Raw
In response to [GENERAL] Ordering of window functions with no order specified?  (Ken Tanzer <ken.tanzer@gmail.com>)
Responses Re: [GENERAL] Ordering of window functions with no order specified?  (Ken Tanzer <ken.tanzer@gmail.com>)
List 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



pgsql-general by date:

Previous
From: Ken Tanzer
Date:
Subject: [GENERAL] Ordering of window functions with no order specified?
Next
From: "David G. Johnston"
Date:
Subject: Re: [GENERAL] Ordering of window functions with no order specified?