2015-07-02 16 views
11

mam te dane:zestaw podejście oparte usunąć zawarte punktów

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) 

Chciałbym usunąć punkty, które są zawarte w innych miejscach, takich jak:

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

uzyskanie zewnętrzna najbardziej punkty określające zewnętrzny wielokąt składający się tylko z pionowych i poziomych linii bez zwolnień (np. (0, 1) jest punktem zbędnym). Czy można to osiągnąć za pomocą opartego na zestawie podejścia TSQL w SQL Server 2014?

PS:

punktowy wykres danych jest w następujący sposób:

enter image description here

Chciałbym usunąć otoczyły punktów. W końcu jestem po zewnętrznej granicy (narysowanej jako czerwone linie). Mam nadzieję, że to wyjaśni.

+1

Jaki jest pożądany wynik? –

+0

Przepraszam, jeśli nie byłam jasna. Usuń punkty: (0, 1), (1, 1), (1,5, 0,5) – cs0815

+0

Dodałem dodatkowe zdjęcie. Nadzieja, która sprawia, że ​​jest jaśniejszy. – cs0815

Odpowiedz

1

Wierzę, że to może zadziałać. Wygląda na to, że dostarczasz swoje dane testowe. Nieco szorstkie. Niektóre z wartości SELECT MIN i SELECT MAX mogą być obliczone z góry, jeśli twoje prawdziwe dane są duże.

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

Niestety tylko wypróbowany i nie działa.On zwraca tylko 3 punkty zamiast 6. – cs0815

+1

@csetkzkorn - ma zwrócić 3 punkty, które chcesz usunąć ... – Fruitbat

+0

Dzięki temu rzeczywiście działa dla podany przykład zaakceptuje to. Dzięki. – cs0815