2015-01-16 2 views
2

В Postgres, у меня есть исторический стол для системы метро, ​​которая имеет такую ​​структуру:В Postgres, как я могу получить подгруппу с максимальным значением для группы?

CREATE TABLE stop_history 
(
    stop_id character varying, 
    route_id character varying, 
    next_stop_id character varying 
); 

Я пытаюсь выяснить: Для остановки и маршрута, что является наиболее распространенной следующей остановкой?

Что мне нужно сделать: Группируйте по остановке, маршрутам и следующей остановке, и получите количество этих групп. Для каждой из этих групп получите группу с наибольшим счетом для каждой комбинации stop_id и route_id.

Как написать такой запрос postgres, и какие индексы я должен разместить в этой таблице, чтобы максимизировать производительность?

Одна из проблем, с которыми я сталкиваюсь, не может использовать count(*) или max(count(*)) в предложении where.

С данными выборки:

INSERT INTO stop_history VALUES ('101N', '1', NULL); 
INSERT INTO stop_history VALUES ('102N', '1', '101N'); 
INSERT INTO stop_history VALUES ('103N', '1', '102N'); 
INSERT INTO stop_history VALUES ('104N', '1', '103N'); 
INSERT INTO stop_history VALUES ('104N', '1', '103N'); 
INSERT INTO stop_history VALUES ('104N', '1', '102N'); 
INSERT INTO stop_history VALUES ('104N', '1', '103N'); 
INSERT INTO stop_history VALUES ('104N', '1', '102N'); 
INSERT INTO stop_history VALUES ('101N', 'D', NULL); 
INSERT INTO stop_history VALUES ('102N', 'D', '101N'); 
INSERT INTO stop_history VALUES ('102N', 'D', '101N'); 
INSERT INTO stop_history VALUES ('102N', 'D', NULL); 

Ожидаемый результат является:

Stop | Route | Most common Next Stop | Frequency 
101N 1 NULL 1 
102N 1 101N 1 
103N 1 102N 1 
104N 1 103N 3 
101N D NULL 1 
102N D 101N 2 
+0

Использование HAVING пункта для агрегатной функции условия! – jarlh

+0

Не могли бы вы выписать запрос :)? –

+0

Как выглядит ваш текущий запрос? – jarlh

ответ

2

Нечто подобное:

select distinct on (stop_id, route_id) stop_id, 
     route_id, 
     coalesce(next_stop_id, 'NULL'), 
     count(*) over (partition by route_id, stop_id, coalesce(next_stop_id, 'NULL')) as frequency 
from stop_history 
order by route_id, stop_id, frequency desc 

Функция окна (count(*) over (...)) подсчитывает частоту next_stop_id колонки ,

В (Postgres) удельная distinct on() затем используется для уменьшения результата только те, с самой высокой частотой (это достигается за счет окончательного order by ... frequence DESC)

SQLFiddle: http://sqlfiddle.com/#!15/66ff6/1

Смежные вопросы