Re: Nested selects

Поиск
Список
Период
Сортировка
От Steve Midgley
Тема Re: Nested selects
Дата
Msg-id 49DE10A9.2000400@misuse.org
обсуждение исходный текст
Ответ на Nested selects  (Glenn Maynard <glennfmaynard@gmail.com>)
Список pgsql-sql
pgsql-sql-owner@postgresql.org wrote:
> Date: Tue, 7 Apr 2009 22:34:38 -0400
> From: Glenn Maynard <glennfmaynard@gmail.com>
> To: pgsql-sql@postgresql.org
> Subject: Nested selects
> Message-ID: <d18085b50904071934g7ad206f1i14ac05f7bd29f05e@mail.gmail.com>
>
> I'm deriving high scores from two tables: one containing data for each
> time a user played (rounds), and one containing a list of stages:
>
> CREATE TABLE stage (id SERIAL NOT NULL PRIMARY KEY, name VARCHAR);
> CREATE TABLE round (id SERIAL NOT NULL PRIMARY KEY, score REAL,
> stage_id INTEGER REFERENCES stage (id));
> INSERT INTO stage (name) VALUES ('stage 1'), ('stage 2'), ('stage 3');
> INSERT INTO round (stage_id, score) VALUES
>   (1, 100), (1, 150), (1, 175),
>   (2, 250), (2, 275), (2, 220),
>   (3, 350), (3, 380), (3, 322);
>
> SELECT r.* FROM round r
> WHERE r.id IN (
>     -- Get the high scoring round ID for each stage:
>     SELECT
>     (
>         -- Get the high score for stage s:
>         SELECT r.id FROM round r
>         WHERE r.stage_id = s.id
>         ORDER BY r.score DESC LIMIT 1
>     )
>     FROM stage s
> );
>
> This works fine, and with a (stage_id, score DESC) index, is
> reasonably fast with around 1000 stages.  round may expand to millions
> of rows.
>
> Unfortunately, it doesn't generalize to getting the top N scores for
> each stage; LIMIT 2 isn't valid ("more than one row returned by a
> subquery used as an expression").
>
> I fiddled with putting the inner results in an array, without much
> luck, and I'm not sure how well that'd optimize.  Having the results
> in any particular order isn't important.  (In practice, the inner
> select will often be more specific--"high scores on the west coast",
> "high scores this month", and so on.)
>
> This seems embarrassingly simple: return the top rounds for each
> stage--but I'm banging my head on it for some reason.
>
>   
How about this:

select round.*, stage.name from round
left join stage on stage.id = round.stage_id
ORDER BY round.score DESC;


Steve



В списке pgsql-sql по дате отправления:

Предыдущее
От: Kashmir
Дата:
Сообщение: Re: join help
Следующее
От: Jasen Betts
Дата:
Сообщение: Re: changing multiple pk's in one update