2015-10-17 19 views
0

我有表示真實世界物理位置的數據。從概念上講,我們可以把它看作:使用INTERSECT的矩陣查詢

|--|---|---|---|---|---| 
    |1A| 2A| 3A| 4A| 5A| 6A| 
    |--|---|---|---|---|---| 
    |1B| 2B| 3B| 4B| 5B| 6B| 
    |--|---|---|---|---|---| 
    |1C| 2C| 3C| 4C| 5C| 6C| 
    |--|---|---|---|---|---| 
    |1D| 2D| 3D| 4D| 5D| 6D| 
    |--|---|---|---|---|---| 
    |1E| 2E| 3E| 4E| 5E| 6E| 
    |--|---|---|---|---|---| 
    |1F| 2F| 3F| 4F| 5F| 6F| 
    |--|---|---|---|---|---| 

一起玩,這裏是DDL/DML:

CREATE TABLE [dbo].[test](
    [x] [int] NOT NULL, 
    [y] [char](10) NOT NULL, 
CONSTRAINT [PK_test] PRIMARY KEY CLUSTERED 
(
    [x] ASC, 
    [y] ASC 
) 
) ON [PRIMARY] 

GO 

INSERT INTO Test(x,y) VALUES(1,'A'); 
INSERT INTO Test(x,y) VALUES(1,'B'); 
INSERT INTO Test(x,y) VALUES(1,'C'); 
INSERT INTO Test(x,y) VALUES(1,'D'); 
INSERT INTO Test(x,y) VALUES(1,'E'); 
INSERT INTO Test(x,y) VALUES(1,'F'); 

INSERT INTO Test(x,y) VALUES(2,'A'); 
INSERT INTO Test(x,y) VALUES(2,'B'); 
INSERT INTO Test(x,y) VALUES(2,'C'); 
INSERT INTO Test(x,y) VALUES(2,'D'); 
INSERT INTO Test(x,y) VALUES(2,'E'); 
INSERT INTO Test(x,y) VALUES(2,'F'); 

INSERT INTO Test(x,y) VALUES(3,'A'); 
INSERT INTO Test(x,y) VALUES(3,'B'); 
INSERT INTO Test(x,y) VALUES(3,'C'); 
INSERT INTO Test(x,y) VALUES(3,'D'); 
INSERT INTO Test(x,y) VALUES(3,'E'); 
INSERT INTO Test(x,y) VALUES(3,'F'); 

INSERT INTO Test(x,y) VALUES(4,'A'); 
INSERT INTO Test(x,y) VALUES(4,'B'); 
INSERT INTO Test(x,y) VALUES(4,'C'); 
INSERT INTO Test(x,y) VALUES(4,'D'); 
INSERT INTO Test(x,y) VALUES(4,'E'); 
INSERT INTO Test(x,y) VALUES(4,'F'); 

INSERT INTO Test(x,y) VALUES(5,'A'); 
INSERT INTO Test(x,y) VALUES(5,'B'); 
INSERT INTO Test(x,y) VALUES(5,'C'); 
INSERT INTO Test(x,y) VALUES(5,'D'); 
INSERT INTO Test(x,y) VALUES(5,'E'); 
INSERT INTO Test(x,y) VALUES(5,'F'); 

INSERT INTO Test(x,y) VALUES(6,'A'); 
INSERT INTO Test(x,y) VALUES(6,'B'); 
INSERT INTO Test(x,y) VALUES(6,'C'); 
INSERT INTO Test(x,y) VALUES(6,'D'); 
INSERT INTO Test(x,y) VALUES(6,'E'); 
INSERT INTO Test(x,y) VALUES(6,'F'); 

事實上,矩陣將超過一百萬X萬,但是如果我能解決這個問題,我將能夠將其應用到我的應用程序。我在程序中遇到的問題是需要顯示的數據量。因爲在這個矩陣中,他們總是對數據網格的外圍感興趣,所以我給他們提供了在網格的四邊之一上看到數據的一個子集的選項。這由Top過濾器和Order by子句管理。

我無法使用x或y的數據值。只有他們如何整理。

例如

select top 2 * 
    from test 
    order by y 

返回上面繪製的矩陣的前兩行。 順序由y遞減返回上下兩排 以便通過X ASC返回左邊兩排
爲了用x遞減返回右邊兩行

上述查詢做了一個無法控制的情況下更容易管理,但現在,他們想要更多。

我被問及是否有任何方法可以讀取矩陣的角落。

|1D| 2D| 3D| 
|--|---|---| 
|1E| 2E| 3E| 
|--|---|---| 
|1F| 2F| 3F| 
|--|---|---| 

這似乎是一個相交會做的伎倆,但我沒有找到成功。我已經嘗試了與遞歸連接的交集,並且我沒有任何運氣。

它你似乎可以查詢前3行和左3行,然後只返回那些具有相同值即交集,但我不斷收回全行。

select top 6 t1.x, t1.y 
    from test t1 
    inner join test t2 on (t1.x = t2.x) and (t1.y = t2.y) 
    intersect 
    select top 6 t2.x, t2.y 
    from test t2 
    inner join test t1 on (t1.x = t2.x) and (t1.y = t2.y) 

看起來這很接近,如果我可以得到一個Order by子句在兩個選擇中工作。

任何幫助表示讚賞。

+0

我明白一個角落意味着什麼時候只需要一個單元格。爲什麼你有'前6名'? –

回答

1

如果你想要角落,爲什麼不按兩列排序?對於左上角:

select top 1 * 
from test 
order by x, y; 

使用ascdesc,以適合其他角落。這可以很好地利用x, y上的索引。

如果你想從一個特定角落的方形電池,那麼你可以做:

select t.* 
from test t 
where t.x in (select top 3 t2.x from test t2 group by t2.x order by t2.x) and 
     t.y in (select top 3 t2.y from test t2 group by t2.y order by t2.y); 

這需要兩個指標,test(x, y)test(y, x)的優勢。

再次在子查詢中使用ascdesc來定義哪個角落。

+0

謝謝戈登。你以簡單的方式拯救了我。 –

0

下面是使用row_number()以得到每個小區的x的另一種方式,y座標,其允許用戶通過where子句

select * from (
    select * , 
     row_number() over (partition by y order by x) xn, 
     row_number() over (partition by x order by y) yn 
    from test 
) t where xn = 1 and yn = 4 

假定每行6個細胞,上述返回查詢中指定的座標來選擇角第二行矩陣的第一個3x3矩陣的左上角,即1D。在一般情況下,檢索kth行矩陣中的nth矩陣(大小mxm)的左上角,你可以使用:where xn = ((n-1)*m)+1 and yn = ((k-1)*m)+1

要檢索的3x3矩陣的所有左上方的角落,你可以使用%操作where xn%3 = 1 and yn%3 = 1

+0

我沒有關注你。你能否將它推向下一個合乎邏輯的步驟? –