sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQLでの(x、y)座標点群の集約

    見過ごされがちな組み込み関数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);
    


    1. MySQL/MariaDBサーバーがいつ起動したかを確認する方法

    2. 式を使用してデータベースのデータをフィルタリングする

    3. ComboBox.ValueMemberおよびDisplayMember

    4. Oracleで日付から月の名前を取得する方法