sql >> Databasteknik >  >> RDS >> PostgreSQL

PostGIS:Fråga z och m dimensioner (linestringzm)

Om du vill kontrollera varje enskild punkt i din LineString kan du ST_DumpPoints dem och hämta M dimension med ST_M . Efter det extraherar delmängden som en LineString som innehåller den överlappande M värden och tillämpa ST_MakeLine med en GROUP BY :

WITH j AS (
  SELECT id,geom,(ST_DumpPoints(geom)).geom AS p 
  FROM t 
) 
SELECT id,ST_AsText(ST_MakeLine(p))
FROM j
WHERE ST_M(p) BETWEEN 1618388000 AND 1618388700
GROUP BY id;

Demo:db<>fiol

Obs :Beroende på din tabell och LineString-storlekar kan denna fråga bli ganska långsam, eftersom värden analyseras i frågetid och därför inte indexeras. Ett mer elegant alternativ vore ..

.. 1) för att skapa en tstzrange kolumn

ALTER TABLE t ADD COLUMN line_interval tstzrange;

.. 2) för att korrekt indexera den

CREATE INDEX idx_t_line_interval ON t USING gist (line_interval);

.. och 3) för att fylla den med tiden för geom är först och sista poäng:

UPDATE t SET line_interval = 
  tstzrange(
    to_timestamp(ST_M(ST_PointN(geom,1))),
    to_timestamp(ST_M(ST_PointN(geom,ST_NPoints(geom)))));

Efter det kan du snabba på saker och ting genom att kontrollera om den indexerade kolumnen överlappar med ett givet intervall. Detta kommer att avsevärt förbättra frågetiden:

SELECT * FROM t
WHERE line_interval && tstzrange(
                        to_timestamp(1618138148), 
                        to_timestamp(1618388700));

Demo:db<>fiol

Mer läsning:




  1. Konvertera en många-till-många-relation till en-till-många i PostgreSQL

  2. Varför visas inte min bild?

  3. SQL-fråga för att få precisionsvärdet för en kolumn

  4. Skapar tabell via SQL Command Line, ogiltig identifierare