見過ごされがちな組み込み関数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
のデモグリッドサイズが原因です。 便利な10進法に一致します。 17
のグリッドサイズで同じことを試してください または何か...
タイムスタンプに拡張
このアプローチを拡張して、date
をカバーすることができます およびtimestamp
extract()を使用して、値を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);