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

行を反復処理し、カスタム距離関数を使用して最も近い一致を見つけるPostgreSQL

    一般的に言えば、JavaまたはScalaで記述されたストアド関数を使用することでこのタイプの問題を解決できます(PL / SQL、CまたはC ++を好む人もいます)。

    PostgreSqlは(Javaベースの)ストアド関数をサポートしているため、SQLクエリでデータをフェッチし、ストアド関数に渡します。ストアド関数は距離を返すので、フィルター/ソートなどを行うことができます。

    このような表に基づく

    create table point(vector float8[]);
    insert into point values('{0.0, 0.0, 0.0}');
    insert into point values('{0.5, 0.5, 0.5}');
    

    次のようなJava関数を使用します:

    public class PlJava {
        public final static double distance2(double[] v1, double[] v2) {
            return Math.sqrt(Math.pow(v2[0] - v1[0], 2)
              + Math.pow(v2[1] - v1[1], 2) + Math.pow(v2[2] - v1[2], 2));
        }
    }
    

    およびSQLでの関数宣言:

    CREATE FUNCTION pljava.distance2(float8[], float8[])
      RETURNS float8
      AS 'PlJava.distance2'
      IMMUTABLE
      LANGUAGE java;
    

    クエリは次のようになります:

    select
        point.*, 
        pljava.distance2(vector, '{1.0, 1.0, 1.0}') as dist
      from
        point 
      order by
        dist;    
    

    その結果

        vector     |       dist  
    ---------------+-------------------  
     {0.5,0.5,0.5} | 0.866025403784439  
     {0,0,0}       |  1.73205080756888  
    

    更新

    保存された関数は、CおよびC++でも記述できます。 PostgreSqlへのインターフェースはC呼び出し規約を使用しているため、C++はより多くの労力を必要とします。 C++を使用した拡張性 を参照してください。



    1. 複合キーの行のグループごとのシリアル番号

    2. ODBC SQLCommand式でSSIS変数を渡す方法は?

    3. PostgresSql9.6の削除が突然遅くなりました

    4. Oracle-行を列に転置