PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

PostgreSQL do iteracji przez wiersze i znalezienia najbliższego dopasowania za pomocą niestandardowej funkcji odległości

Ogólnie rzecz biorąc, możesz rozwiązać tego typu problemy za pomocą funkcji przechowywanej, napisanej w Javie lub Scali (niektórzy mogą preferować PL/SQL, C lub C++).

PostgreSql obsługuje (bazujące na Javie) funkcje składowane, więc niech zapytanie SQL pobierze dane i przekaże je do funkcji składowanej. Przechowywana funkcja zwraca odległość, dzięki czemu można na niej filtrować/sortować itp.

Na podstawie tabeli takiej jak ta

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

z funkcją Java taką jak ta:

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

oraz deklaracja funkcji w SQL:

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

Twoje zapytanie może wyglądać tak:

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

co skutkuje

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

Aktualizuj

Przechowywane funkcje można również pisać w językach C i C++. C++ wymaga więcej wysiłku, ponieważ interfejs do PostgreSql używa konwencji wywoływania C. Zobacz Wykorzystywanie C++ do rozszerzania



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgres:Ograniczenie z zaznaczeniem tylko na INSERT

  2. Funkcja, która działa w nieskończoność dla dużej liczby rekordów

  3. Jak połączyć R z PostgreSQL na OSX 10.10.2?

  4. Jak pg_column_size może być mniejszy niż octet_length?

  5. Czy istnieje skrót do SELECT * FROM?