2015-07-02 10 views
11

ho questi dati:set approccio per rimuovere contenute punti

IF OBJECT_ID('tempdb..#temp') IS NOT NULL 
    DROP TABLE #temp 
CREATE TABLE #temp 
    (
     Id INT IDENTITY(1, 1) , 
     X FLOAT NOT NULL , 
     Y FLOAT NOT NULL 
    ) 

INSERT INTO #temp (X, Y) VALUES (0, 0) 
INSERT INTO #temp (X, Y) VALUES (0, 1) 
INSERT INTO #temp (X, Y) VALUES (0, 2) 
INSERT INTO #temp (X, Y) VALUES (0.5, 1) 
INSERT INTO #temp (X, Y) VALUES (1, 1) 
INSERT INTO #temp (X, Y) VALUES (1, 2) 
INSERT INTO #temp (X, Y) VALUES (1.5, 0.5) 
INSERT INTO #temp (X, Y) VALUES (2, 0) 
INSERT INTO #temp (X, Y) VALUES (2, 1) 

Vorrei rimuovere i punti che sono contenuti all'interno di altri punti, come:

(0, 1) 
(1, 1) 
(1.5, 0.5) 

per ottenere la più esterna punti che definiscono il poligono esterno costituito da sole linee verticali e orizzontali senza ridondanze (es. (0, 1) è un punto ridondante). Questo può essere ottenuto con un approccio TSQL basato su set in SQL Server 2014?

PS:

Un grafico a dispersione dei dati è la seguente:

enter image description here

vorrei togliere i punti circondato. In definitiva, sono dopo il bordo esterno (disegnato come linee rosse). Spero che questo lo renda più chiaro.

+1

Quindi qual è il risultato desiderato? –

+0

Scusa se non ero chiaro. Rimuovi i punti: (0, 1), (1, 1), (1.5, 0.5) – cs0815

+0

Ho aggiunto un'immagine aggiuntiva. Spero che lo renda più chiaro. – cs0815

risposta

1

Credo che questo potrebbe funzionare. Sembra fornire i dati del test. Un po 'ruvido. Alcuni dei SELECT MIN e SELECT MAX potrebbero forse essere calcolati in anticipo se i tuoi dati reali sono grandi.

SELECT * 
-- uncomment this to delete the desired points 
-- DELETE #temp 
FROM #temp t 
WHERE 
(
    -- Internal points 
    (
      (X > (SELECT MIN(X) FROM #temp) AND X < (SELECT MAX(X) FROM #temp)) 
     AND (Y > (SELECT MIN(Y) FROM #temp) AND Y < (SELECT MAX(Y) FROM #temp)) 
    ) 
    -- Exceptions (points with nothing strictly outside them) [Don't want to lose (1,1)] 
    AND EXISTS (SELECT * FROM #temp WHERE X > t.X AND Y > t.Y) 
) 
OR 
    -- redundant edge points [(0,1) would be included as an "exception"] 
(
    ((t.X = (SELECT MIN(X) FROM #temp) OR t.X = (SELECT MAX(X) FROM #temp)) 
     AND EXISTS (SELECT * FROM #temp WHERE X = t.X AND Y > t.Y) 
     AND EXISTS (SELECT * FROM #temp WHERE X = t.X AND Y < t.Y) ) 
    OR 
    ((t.Y = (SELECT MIN(Y) FROM #temp) OR t.Y = (SELECT MAX(Y) FROM #temp)) 
     AND EXISTS (SELECT * FROM #temp WHERE Y = t.Y AND X > t.X) 
     AND EXISTS (SELECT * FROM #temp WHERE Y = t.Y AND X < t.X) ) 
) 
+0

Scusa l'ho appena provato e non funziona, restituisce solo 3 punti anziché 6. – cs0815

+1

@csetkzkorn - si suppone che restituisca i 3 punti che si desidera eliminare ... – Fruitbat

+0

l'esempio dato. Quindi io accetterà questo. Grazie. – cs0815

Problemi correlati