Подсчет количества различных мест, обслуживаемых одним и тем же транспортным средством postgresql - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть таблица, похожая на следующую:

CREATE TABLE movements (
    "id" integer,
    "date" timestamp with time zone,
    "origin" character varying(255),
    "destination" character varying(255),
    "vehicle" character varying(255)   
);

INSERT INTO movements (id,date,origin,destination,vehicle)
 VALUES (1, '2017-11-01 00:00:00+00', 'loc_A', 'loc_B', 'V1'),
    (2, '2017-11-01 00:00:00+00', 'loc_C', 'loc_B', 'V1'),
    (3, '2017-11-01 00:00:00+00', 'loc_D', 'loc_B', 'V1'),
    (4, '2017-11-02 00:00:00+00', 'loc_E', 'loc_B', 'V1'),
    (5, '2017-11-02 00:00:00+00', 'loc_A', 'loc_B', 'V2'),
    (6, '2017-11-02 00:00:00+00', 'loc_F', 'loc_B', 'V2');

Как подсчитать количество различных мест происхождения, которые использовали одни и те же транспортные средства для каждого места происхождения, а также среднее и максимальное количество мест происхожденияместоположения, которые использовали одно и то же транспортное средство для местоположения отправления в тот же день?

В этом случае будет вывод типа

location, total, daily_mean, daily_max
loc_A   ,     4,        1.5,        2
loc_C   ,     3,          2,        2
loc_D   ,     3,          2,        2
loc_E   ,     3,          0,        0
loc_F   ,     1,          1,        1

1 Ответ

0 голосов
/ 05 декабря 2018

Исходя из того, что вы описали, я думаю, что ниже должно работать.Он использует самосоединение для вычисления статистики по дням в общем табличном выражении, а затем агрегирует по дням, чтобы получить нужные столбцы.Чтобы получить общий список, мы раскручиваем списки местоположений для отдельных дней, а затем снова объединяем их в массив, что может быть не идеально по сравнению с использованием подзапроса в базовой таблице, но, надеюсь, этого достаточно:

with day_values as (
    select m.origin, m.date
   , count(distinct m2.origin) as locations_with_shared_vehicle
   , array_agg(distinct m2.origin) as location_list
  from movements m
  join movements m2
   on m2.vehicle = m.vehicle
   and m2.date = m.date
   and m2.origin <> m.origin
  group by m.origin, m.date )

select t.origin as location
 , array_length( (select array( SELECT DISTINCT unnest(t2.location_list)  from day_values t2 WHERE t2.origin = t.origin) ), 1) AS total_locations
, avg(locations_with_shared_vehicle) as daily_mean
 , max(locations_with_shared_vehicle) as daily_max
from day_values t
 group by t.origin
 order by t.origin;

Скрипка: http://sqlfiddle.com/#!17/00daa/1/0

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