基于集合的方法来删除包含的点
set based approach to remove contained points
我有这个数据:
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)
我想删除包含在其他点中的点,例如:
(0, 1)
(1, 1)
(1.5, 0.5)
获取定义仅由垂直线和水平线组成的外部多边形的最外点,没有冗余(例如(0, 1)是冗余点)。这可以通过 SQL Server 2014 中基于集合的 TSQL 方法来实现吗?
PS:
数据散点图如下:
我想删除圈出的点。最终,我在外边界之后(绘制为红线)。希望这能让它更清楚。
我相信这可能有效。它似乎可以提供您的测试数据。
有点粗糙。如果你的实际数据很大,一些 SELECT MIN 和 SELECT MAX 可能可以提前计算。
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) )
)
我有这个数据:
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)
我想删除包含在其他点中的点,例如:
(0, 1)
(1, 1)
(1.5, 0.5)
获取定义仅由垂直线和水平线组成的外部多边形的最外点,没有冗余(例如(0, 1)是冗余点)。这可以通过 SQL Server 2014 中基于集合的 TSQL 方法来实现吗?
PS:
数据散点图如下:
我想删除圈出的点。最终,我在外边界之后(绘制为红线)。希望这能让它更清楚。
我相信这可能有效。它似乎可以提供您的测试数据。 有点粗糙。如果你的实际数据很大,一些 SELECT MIN 和 SELECT MAX 可能可以提前计算。
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) )
)