Re: Need to overcome UNION / ORDER BY restriction

Lists: pgsql-sql
From: "Timo" <siroco(at)suomi24(dot)fi>
To: pgsql-sql(at)postgresql(dot)org
Subject: Need to overcome UNION / ORDER BY restriction
Date: 2003-09-29 14:27:47
Message-ID: bl9fh3$1krk$1@news.hub.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-sql


I have a table:

id | priority | seniority
-----+----------+-----------
902 | 2 | 271
902 | 1 | 271
902 | 3 | 271
924 | 2 | 581
924 | 1 | 581
924 | 3 | 581
935 | 1 | 276
935 | 2 | 276
972 | 2 | 275
(9 rows)

I'd need to get a result set where rows are sorted according to these rules:

1. first all rows with priority = 1 sorted according to seniority
2. then the rest of the rows sorted by seniority, priority

Something like this:

SELECT * from foo where priority = 1 order by seniority
union select * from foo where priority > 1 order by seniority, priority

but this gives parse error because of the restrictions with ORDER BY and
UNION (I suppose..)

select * from foo order by case when priority = 1 then priority else
seniority end;

goes fine, but it's not quite enough and when I try

select * from foo order by case when priority = 1 then priority else
seniority, priority end;

it's parse error at or near ",".

Any suggestions?

Thanks in advance,
Timo

---------------

CREATE TABLE foo (
id integer,
priority integer,
seniority integer
);

INSERT INTO foo VALUES (902, 2, 271);
INSERT INTO foo VALUES (902, 1, 271);
INSERT INTO foo VALUES (902, 3, 271);
INSERT INTO foo VALUES (924, 2, 581);
INSERT INTO foo VALUES (924, 1, 581);
INSERT INTO foo VALUES (924, 3, 581);
INSERT INTO foo VALUES (935, 1, 276);
INSERT INTO foo VALUES (935, 2, 276);
INSERT INTO foo VALUES (972, 2, 275);


From: Bruno Wolff III <bruno(at)wolff(dot)to>
To: Timo <siroco(at)suomi24(dot)fi>
Cc: pgsql-sql(at)postgresql(dot)org
Subject: Re: Need to overcome UNION / ORDER BY restriction
Date: 2003-09-29 17:15:03
Message-ID: 20030929171503.GA10856@wolff.to
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-sql

On Mon, Sep 29, 2003 at 17:27:47 +0300,
Timo <siroco(at)suomi24(dot)fi> wrote:
>
> I'd need to get a result set where rows are sorted according to these rules:
>
> 1. first all rows with priority = 1 sorted according to seniority
> 2. then the rest of the rows sorted by seniority, priority

You can do something like:
bruno=> select * from foo order by priority <> 1, seniority, priority;
id | priority | seniority
-----+----------+-----------
902 | 1 | 271
935 | 1 | 276
924 | 1 | 581
902 | 2 | 271
902 | 3 | 271
972 | 2 | 275
935 | 2 | 276
924 | 2 | 581
924 | 3 | 581
(9 rows)


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "Timo" <siroco(at)suomi24(dot)fi>
Cc: pgsql-sql(at)postgresql(dot)org
Subject: Re: Need to overcome UNION / ORDER BY restriction
Date: 2003-09-29 18:06:39
Message-ID: 26825.1064858799@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-sql

"Timo" <siroco(at)suomi24(dot)fi> writes:
> SELECT * from foo where priority = 1 order by seniority
> union select * from foo where priority > 1 order by seniority, priority
> but this gives parse error because of the restrictions with ORDER BY and
> UNION (I suppose..)

You'd need to parenthesize:

(SELECT * from foo where priority = 1 order by seniority)
UNION ALL
(select * from foo where priority > 1 order by seniority, priority)

Otherwise the ORDER BY is considered to apply to the whole UNION result
(it's effectively got lower binding priority than the UNION). Note also
that you *must* use UNION ALL, else UNION will attempt to eliminate
duplicates, and mess up the sort order while at it.

See also Bruno's solution nearby. Not sure which of these approaches
would be faster; try both.

regards, tom lane