如何计算按网格中的单元格分组的SQL?

时间:2018-10-29 13:26:25

标签: sql oracle group-by geometry

我使用SQL,并且希望计算尺寸变化的网格中的点数。

我找到了一个解决方案,但我想知道是否有一种更优雅或更有效的方法来专注于Oracle。

这是我的数据依据:

create table tmpa (
  x number(10, 2),
  y number(10, 2),
  val number
);

insert into tmpa values (1.0, 1.8, 9);
insert into tmpa values (1.9, 2.0, 9);
insert into tmpa values (2.1, 1.9, 9);
insert into tmpa values (2.2, 2.6, 9);
insert into tmpa values (2.6, 2.7, 9);
insert into tmpa values (3.1, 3.9, 9);
insert into tmpa values (3.4, 3.7, 9);
insert into tmpa values (3.7, 3.8, 9);

让我们假设xy已正确索引。 这大致代表一个平面中的点。

现在,我想计算网格单元中的点数。网格始于(xmin,ymin),结束于(xmax,ymax),每个网格均分为cells个部分。

例如,如下所示:

  |       |       |       |
--+-------+-------+-------+-- 4.7
  |       |       |       |
  |       |    *  |       |
  |       |     * | *     |
--+-------+-------+-------+-- 3.5
  |       |       |       |
  |       |  *    |       |
  |     * |       |       |
--+-------+-------+-------+-- 2.3
  |       |       |       |
o |    ** |       |       |
  |       |       |       |
--+-------+-------+-------+-- 1.1
  |       |       |       |
 1.1     2.3     3.5     4.7

cells3xminymin1.1xmaxymax是{{1} },导致像元大小(4.7dx)为dy

现在,我想计算每个单元格中的点数。为了方便起见,我也可以将中心点作为查询结果。

结果如下:

1.2

我不介意列出计数为零的行。

这正是以下查询输出的结果:

xcell ycell COUNT   center
  0,    0,    2,   1.65,1.65
  0,    1,    1,   1.65,2.85
  1,    1,    1,   2.85,2.85
  1,    2,    2,   2.85,4.05
  2,    2,    1    4.05,4.05

但是这比我想的要复杂。而且我不知道这有多有效。也许有一个非常高效或非常简单的查询,我只是看不到。

注意:我不想使用地理或空间扩展。

更新:我删除了-- 1.1: xmin, 4.7: xmax, cells:3, 1.2:(xmax-xmin)/cells ; same with y Select d2.xcell, d2.ycell, d2.cnt, d2.xcell*1.2+1.1+1.1/2 xcenter, d2.ycell*1.2+1.1+1.1/2 ycenter From ( SELECT d1.xcell, d1.ycell, count(*) cnt FROM ( select floor((x-1.1)/1.2) xcell, floor((y-1.1)/1.2) ycell from tmpa ) d1 where d1.xcell>=1.1 and d1.xcell<4.7 and d1.ycell>=1.1 and d1.ycell<4.7 group by xcell, ycell ) d2 Order By d2.xcell, d2.ycell ; ,因为对于半开间隔,between>=更好。

1 个答案:

答案 0 :(得分:1)

这等效于您的查询,但没有一些子查询子查询:

select xcell, ycell, cnt, xcell*1.2+1.1+1.1/2 as xcenter, ycell*1.2+1.1+1.1/2 ycenter
from (select floor((x-1.1)/1.2) as xcell, floor((y-1.1)/1.2) as ycell, count(*) as cnt
      from tmpa
      where xcell >= 1.1 and xcell < 4.7 and 
            ycell >= 1.1 and ycell < 4.7
      group by floor((x-1.1)/1.2), floor((y-1.1)/1.2)
     ) d
order By xcell, ycell;

这也通过将between替换为适当的不等式来解决边界问题。