PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Агрегиране на (x,y) облаци от координатни точки в PostgreSQL

Използвайте често пренебрегваната вградена функция width_bucket() в комбинация с вашата агрегация:

Ако вашите координати са от, да речем, 0 до 2000 и искате да консолидирате всичко в квадрати от 5 до единични точки, бих изложил мрежа от 10 (5*2) по следния начин:

SELECT device_id
     , width_bucket(pos_x, 0, 2000, 2000/10) * 10 AS pos_x
     , width_bucket(pos_y, 0, 2000, 2000/10) * 10 AS pos_y
     , count(*) AS ct -- or any other aggregate
FROM   tbl
GROUP  BY 1,2,3
ORDER  BY 1,2,3;

Засвеждане до минимум на грешката можете да GROUP BY мрежата, както е показано, но запазете действителните средни координати:

SELECT device_id
     , avg(pos_x)::int AS pos_x   -- save actual averages to minimize error
     , avg(pos_y)::int AS pos_y   -- cast if you need to
     , count(*)        AS ct      -- or any other aggregate
FROM   tbl
GROUP  BY
       device_id
     , width_bucket(pos_x, 0, 2000, 2000/10) * 10  -- aggregate by grid
     , width_bucket(pos_y, 0, 2000, 2000/10) * 10
ORDER  BY 1,2,3;

sqlfiddle, демонстриращ и двете заедно.

Е, този конкретен случай може да е по-прост:

...
GROUP  BY
       device_id
     , (pos_x / 10) * 10          -- truncates last digit of an integer
     , (pos_y / 10) * 10
...

Но това е само защото размерът на демонстрационната мрежа е 10 удобно съвпада с десетичната система. Опитайте същото с размер на мрежата 17 или нещо...

Разгъване до времеви печати

Можете да разширите този подход, за да обхване date и timestamp стойности, като ги преобразувате в unix епоха (брой секунди от '1970-1-1') с екстракт ().

SELECT extract(epoch FROM '2012-10-01 21:06:38+02'::timestamptz);

Когато сте готови, преобразувайте резултата обратно в timestamp with time zone :

SELECT timestamptz 'epoch' + 1349118398 * interval '1s';

Или просто to_timestamp() :

SELECT to_timestamp(1349118398);


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Еквивалентни на MySQL HEX() и UNHEX() в Postgres?

  2. Как да стигнем до края на деня?

  3. Как да изтрия стойност на тип enum в postgres?

  4. Как да разделите таблица на postgres с помощта на междинна таблица

  5. Създайте уникално ограничение с нулеви колони