2016-07-17 47 views
0

我有一個表,我映射基於X和值y座標(XY是主鍵)如何查詢連接座標?

+---+---+--------+--------+ 
| X | Y | Data 1 | Data 2 | 
+---+---+--------+--------+ 

比方說,我有一個存儲的值有:

X → 
    1234567 
Y 1|XXXX X| 
↓ 2| XX X| 
    3| X X| 
    4| X XX| 
    5| X XXXX| 

如何建立一個SQL查詢來獲取所有連接的值作爲結果?獲取順序並不重要。

例如,如果我查詢:

  • X=3Y=2它取:(1,1),(2,1),(3,1),(4,1),(2,2),(3,2)
  • X=5Y=3它取:(5,3)
  • X=2Y=4它取:(2,4),(2,5)
  • X=7Y=3它提取:(4,5),(5,5),(6,4),(6,5),(7,1),(7,2),(7,3),(7,4),(7,5)

示例表作爲SQL:

DROP TABLE IF EXISTS `test`; 
CREATE TABLE `test` (
    `x` int(11) NOT NULL, 
    `y` int(11) NOT NULL, 
    PRIMARY KEY (`x`,`y`) 
); 
INSERT INTO `test` VALUES 
(1, 0),(1, 1),(2, 2),(2, 4),(2, 5),(3, 1),(3, 2),(4, 1),(4, 5), 
(5, 0),(5, 5),(6, 4),(6, 5),(7, 1),(7, 2),(7, 3),(7, 4),(7, 5); 

回答

1

我不認爲這是可能的SQL。您需要將數據加載到二維布爾矩陣中並實現搜索算法。你從一個點開始,遞歸搜索所有8個方向,並添加一個X到一個集。停止找到空位。

這有點類似於繪畫程序中的區域填充算法。

您可以通過向每個座標發佈單個SQL直接在數據庫中進行搜索,但它不會非常有效。

0

這可以通過在4個方向上進行一些遞歸** SQL路徑搜索來完成,但是我覺得你不能在單個查詢中完成......從任何X'd點開始,可以使用查詢步驟圍繞4個方向,如果找到X'es,則使用相同查詢的遞歸調用來調查該目標的上下文..但是您將希望避免循環循環和相鄰之間的翻轉。在每一個地方,都需要一個「遮蔽位置」的過濾器。你會發現每一個組中只有一個組。要查找所有組,您需要運行更多查詢。

爲了避免太多的測試,我會沿方形場的邊界放置一個空單元格帶,並迭代1..N-2而不是0..N-1。

平臺:工作可以用存儲過程中的查詢完成。但寧可考慮而不是爲此使用SQL。使用CLR調用可能會更方便,大部分問題都是用c#編碼的。您可以從存儲過程實現引用您的classlib DLL的函數。

******沒有看標籤!在MySql中沒有遞歸選擇..所以答案是「否」無論如何

2

你問的問題可以通過一個公用的表達式來實現。

我在本例中使用TSQL,但可以使用其他SQL方言構建類似的查詢。

允許第一起始與列出了所有相鄰小區的視圖:

create view [dbo].[fromto] as 
select 
t1.x as x_from, 
t1.y as y_from, 
t2.x as x_to, 
t2.y as y_to 
from test t1 
join test t2 on t2.x = t1.x and t2.y = t1.y + 1 
union 
select 
t1.x as x_from, 
t1.y as y_from, 
t2.x as x_to, 
t2.y as y_to 
from test t1 
join test t2 on t2.x = t1.x and t2.y = t1.y - 1 
union 
select 
t1.x as x_from, 
t1.y as y_from, 
t2.x as x_to, 
t2.y as y_to 
from test t1 
join test t2 on t2.x = t1.x + 1 and t2.y = t1.y 
union 
select 
t1.x as x_from, 
t1.y as y_from, 
t2.x as x_to, 
t2.y as y_to 
from test t1 
join test t2 on t2.x = t1.x - 1 and t2.y = t1.y 

現在我們要遞歸通過該視圖迭代:

with walk (x_col_from, y_col_from, x_col_to, y_col_to, stack) as(
select 
x_from, 
y_from, 
x_to, 
y_to, 
cast(concat('|',x_from ,',',y_from, '|', x_to, ',', y_to) as varchar) 
from fromto 
union all 
select 
walk.x_col_from, 
walk.y_col_from, 
fromto.x_to, 
fromto.y_to, 
cast(concat(walk.stack,'|',fromto.x_to,',',fromto.y_to) as varchar) 
from fromto 
join walk on walk.x_col_to = fromto.x_from and walk.y_col_to = fromto.y_from 
where CHARINDEX(cast(concat('|',fromto.x_to,',',fromto.y_to) as varchar), walk.stack) = 0 
) 
select * from walk 

堆棧字段用於memoize的細胞我們已經訪問過。它也提供了通過網格的路徑。

+0

哇...現在這是一個複雜的查詢你在這裏呈現。 +1 \ – Goodies