Как я могу использовать PostGIS, чтобы выбрать среднюю цену ближайших X мест? - PullRequest
2 голосов
/ 27 апреля 2020

Я бы хотел узнать среднюю цену на газ для любого дома. Вот мои текущие таблицы.

home_id  | geocoordinates
1        | 0101000020E61000005BB6D617097544
2        | 0101000020E61000005BB6D617097545
3        | 0101000020E61000005BB6D617097546
4        | 0101000020E61000005BB6D617097547
5        | 0101000020E61000005BB6D617097548

gas_price   |   geocoordinates
1           |   0101000020E61000005BB6D617097544
1           |   0101000020E61000005BB6D617097545
1           |   0101000020E61000005BB6D617097546
2           |   0101000020E61000005BB6D617097547
2           |   0101000020E61000005BB6D617097548
2           |   0101000020E61000005BB6D617097544
2           |   0101000020E61000005BB6D617097545
3           |   0101000020E61000005BB6D617097546
3           |   0101000020E61000005BB6D617097547
3           |   0101000020E61000005BB6D617097548
3           |   0101000020E61000005BB6D617097544
4           |   0101000020E61000005BB6D617097545
4           |   0101000020E61000005BB6D617097546
4           |   0101000020E61000005BB6D617097547

Для каждого дома я бы хотел найти среднюю цену на газ по X ближайшим gas_prices. Пример, если X = 5:

home_id     |   average_of_closest_five_gas_prices
1           |   1.5
2           |   2.5
3           |   2.1
4           |   1.5
5           |   1.5

Я понял, что использовал один отдельный home_id, но я пытаюсь понять, как это сделать для всех.

select avg(gas_price) from (
                               SELECT *
                               FROM gas_price
                               ORDER BY gas_price.geocoordinates <-> '0101000020E61000005BB6D617097544'
                               LIMIT 5
                           ) as table_a

1 Ответ

3 голосов
/ 28 апреля 2020

Вы можете использовать боковое соединение , чтобы ограничить размер группы в group by.

select home_id, avg(gas_price)
  from home,
    lateral (
      select gas_price
        from gas_price
        order by gas_price.geocoordinates <-> home.geocoordinates
        limit 5
    ) x
  group by home_id;

Другой вариант - использовать оконную функцию: разделить на home_id, упорядочить по расстоянию и выберите только строки с row_number() <= 5.

select home_id, avg(gas_price)
  from (
    select row_number() over w as r, *
      from home h, gas_price g
      window w as (partition by home_id order by g.geocoordinates <-> h.geocoordinates)
    ) x
  where r <= 5
  group by home_id;
...