2015-10-17 54 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

我没有关注你。你能否将它推向下一个合乎逻辑的步骤? –