Выбор столбцов с помощью DISTINCT в PostgreSQL - PullRequest
6 голосов
/ 15 февраля 2011

Я запрашиваю автобусные остановки из базы данных, и я хочу, чтобы она возвращала только 1 остановку на одну автобусную линию / направление. Этот запрос делает именно это:

Stop.select("DISTINCT line_id, direction")

За исключением того, что он не даст мне никакого другого атрибута, кроме этих 2. Я попытался сделать несколько других запросов, чтобы он возвращал id в дополнение к полям line_id и direction (в идеале он должен был бы вернуть все столбцы), не повезло:

Stop.select("DISTINCT line_id, direction, id")

и

Stop.select("DISTINCT(line_id || '-' || direction), id")

В обоих случаях запрос теряет свое отдельное предложение и возвращаются все строки.

Какой-то удивительный чувак помог мне и предложил использовать подзапрос, чтобы он возвращал все идентификаторы:

Stop.find_by_sql("SELECT DISTINCT a1.line_id, a1.direction, (SELECT a2.id from stops a2 where a2.line_id = a1.line_id AND a2.direction = a1.direction ORDER BY a2.id ASC LIMIT 1) as id FROM stops a1

Затем я могу извлечь все идентификаторы и выполнить второй запрос, чтобы получить полные атрибуты для каждой остановки.

Есть ли способ получить все это в одном запросе и вернуть ли все атрибуты?

Ответы [ 2 ]

27 голосов
/ 16 февраля 2011
Stop.select("DISTINCT ON (line_id, direction) *")
3 голосов
/ 16 февраля 2011

Не так быстро - другой ответ выбирает stop_id произвольно

Вот почему ваш вопрос не имеет смысла.Мы можем получить stop_ids и иметь разные line_id и направление.Но мы понятия не имеем, почему у нас есть stop_id.

    create temp table test( line_id integer, direction char(1), stop_id      integer);
    insert into test values
            (1, 'N', 1),
            (1, 'N', 2),
            (1, 'S', 1),
            (1, 'S', 2),
            (2, 'N', 1),
            (2, 'N', 2),
            (2, 'S', 1),
            (2, 'S', 2)
    ;
    select distinct on (line_id, direction) * from test;
    -- do this again but will reverse the order of stop_ids
    -- could it possible change our Robust Query?!!!
    drop table test;
    create temp table test(line_id integer,direction char(1),stop_id integer);
    insert into test values
            (1, 'N', 2),
            (1, 'N', 1),
            (1, 'S', 2),
            (1, 'S', 1),
            (2, 'N', 2),
            (2, 'N', 1),
            (2, 'S', 2),
            (2, 'S', 1)
    ;
    select distinct on (line_id, direction) * from test;

Первый выбор:

line_id | direction | stop_id 
---------+-----------+---------
       1 | N         |       1
       1 | S         |       1
       2 | N         |       1
       2 | S         |       1

Второй выбор:

line_id | direction | stop_id 
---------+-----------+---------
       1 | N         |       2
       1 | S         |       2
       2 | N         |       2
       2 | S         |       2

Итак, мы ушлибез группировки stop_id, но у нас нет никаких гарантий, почему мы получили тот, который сделали.Все, что мы знаем, это то, что это правильный stop_id.Любые обновления, вставки и другие вещи, которые не гарантирует RDMS, могут меняться в зависимости от физического порядка строк.

Это то, что я имел в виду в верхнем комментарии.Нет никакой известной причины для перетаскивания одного stop_id поверх другого, но каким-то образом вам нужен этот stop_id (или любой другой) отчаянно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...