代码之家  ›  专栏  ›  技术社区  ›  towi

如何使用网格中按单元格分组的SQL进行计数?

  •  1
  • towi  · 技术社区  · 6 年前

    我使用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);
    

    让我们假设 x y 已正确索引。

    (xmin,ymin) (xmax,ymax) 各分为 cells 部分。

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

    细胞 3 在这里 xmin ymin 1.1 xmax ymax 4.7 ,从而产生单元格大小( dx 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 回复  |  直到 6 年前
        1
  •  1
  •   Gordon Linoff    6 年前

    这相当于您的查询,但没有一些子查询子查询:

    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 具有适当的不平等性。