sql >> Databasteknik >  >> RDS >> PostgreSQL

Skapa anpassad likhetsoperatör för PostgreSQL-typ (punkt) för DISTINCT-samtal

För att välja distinkta värden måste Postgres ha möjlighet att sortera kolumnen. Du måste skapa ett komplett bträd operatörsklass för typpunkt, dvs fem operatorer (< , <= , = , >= , > ) och en funktion som jämför två punkter och returnerar heltal, som det beskrivs i den dokumentation .

För operatören = du kan använda den befintliga funktionen point_eq(point, point) :

create operator = (leftarg = point, rightarg = point, procedure = point_eq, commutator = =);

Exempeldefinition av operator < :

create function point_lt(point, point)
returns boolean language sql immutable as $$
    select $1[0] < $2[0] or $1[0] = $2[0] and $1[1] < $2[1]
$$;

create operator < (leftarg = point, rightarg = point, procedure = point_lt, commutator = >);

Definiera operatorerna <= , => och > på ett liknande sätt. Med alla fem operatörerna, skapa en funktion:

create function btpointcmp(point, point)
returns integer language sql immutable as $$
    select case 
        when $1 = $2 then 0
        when $1 < $2 then -1
        else 1
    end
$$;

Och slutligen:

create operator class point_ops
    default for type point using btree as
        operator 1 <,
        operator 2 <=,
        operator 3 =,
        operator 4 >=,
        operator 5 >,
        function 1 btpointcmp(point, point);

Med klassen point_ops definierat kan du välja distinkta punktvärden och ordna rader efter kolumnen typpunkt, t.ex.:

with q(p) as (
    values 
        ('(1,1)'::point),
        ('(1,2)'::point),
        ('(2,1)'::point),
        ('(1,1)'::point))
select distinct *
from q
order by 1 desc;

   p   
-------
 (2,1)
 (1,2)
 (1,1)
(3 rows)    

Du kan också skapa (unikt) index på en punktkolumn.

Uppdatering.

Postgres har över 2800 hjälpfunktioner som stöder operatörer, index, standardfunktioner etc. Du kan lista dem genom att fråga pg_proc , t.ex.:

select format('%s(%s)', proname, pg_get_function_arguments(oid))
from pg_proc
where pronamespace::regnamespace = 'pg_catalog'
and proname like 'point%'

Funktionen point_eq(point, point) används vid implementering av vissa geometriska funktioner och operatorer.




  1. Kan du använda en MySQL-fråga för att helt skapa en kopia av databasen

  2. PHP- infoga binär data i mysql med hjälp av förberedda satser

  3. Går med till MAX datumpost i grupp

  4. MySQL konverterar datumsträng till Unix tidsstämpel