sql >> Databasteknik >  >> RDS >> PostgreSQL

PostgreSQL för att iterera genom rader och hitta den närmaste matchningen med hjälp av anpassad avståndsfunktion

Generellt sett kan du lösa den här typen av problem genom att använda en lagrad funktion, skriven i Java eller Scala (vissa kanske föredrar PL/SQL, C eller C++).

PostgreSql stöder (Java-baserade) lagrade funktioner, så låt SQL-frågan hämta data och skicka den till en lagrad funktion. Den lagrade funktionen returnerar avståndet, så att du kan filtrera/sortera etc. på det.

Baserat på en tabell som denna

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}');

med en Java-funktion så här:

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));
    }
}

och funktionsdeklarationen i SQL:

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

din fråga kan se ut så här:

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

vilket resulterar i

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

Uppdatera

Lagrade funktioner kan också skrivas i C och C++. C++ kräver mer ansträngning, eftersom gränssnittet till PostgreSql använder C-anropskonventionen. Se Använda C++ för utökningsbarhet



  1. Filtrera rader i en kolumn baserat på uppställda regler i SQL

  2. Lagring av SQLite-databas med Android och Phonegap

  3. LPAD utan trimning i mysql

  4. Mysql till Postgresql konverteringsverktyg i Java