【问题标题】:Get frequency distribution of a decimal range in MySQL获取MySQL中小数范围的频率分布
【发布时间】:2011-12-26 15:12:52
【问题描述】:

我正在寻找一种优雅的方式(就语法而言,不一定有效)来获取小数范围的频率分布。

例如,我有一个带有评级列的表,它可以是负数也可以是正数。我想获得具有一定范围评级的行的频率。 - ... - [-140.00 到 -130.00):5 - [-130.00 到 -120.00):2 - [-120.00 到 -110.00):1 - ... - [120.00 至 130.00): 17 - 等等。

[i to j) 表示 i 包含到 j 不包含。

提前致谢。

【问题讨论】:

  • -130分两套,是你想要的吗?
  • 你可以使用'select floor(rating / 10), count(*) from (table) group by 1'得到非常接近的结果
  • 嗨@xQbert,另一个是-130,另一个是+130。
  • @ethrbunny:优雅的解决方法!如果您愿意,请将此作为答案,我会投票赞成。 :D
  • 我想我的观点是 -140 到 -130,然后 -130 到 -120 在两组中都包括 -130。因此有一些加倍的可能性;但是 ethrbunny 把它钉在了 imo 上

标签: mysql sql


【解决方案1】:

您可以使用“select floor(rating / 10), count(*) from (table) group by 1”得到非常接近的结果

【讨论】:

  • 为好的答案和惊人的处理点赞!但是,我认为round() 在这里更合适。记住数据的规模分布也很重要。相应地调整您的舍入精度。
【解决方案2】:

我在想一些可以做很多级别的东西,比如

DELIMITER $$  
CREATE PROCEDURE populate_stats()

   BEGIN
      DECLARE range_loop INT Default 500 ;
      simple_loop: LOOP
         SET the_next = range_loop - 10;
         Select sum(case when range between range_loop and the_next then 1 else 0 end) from table,
         IF the_next=-500 THEN
            LEAVE simple_loop;
         END IF;
   END LOOP simple_loop;
END $$



usage: call populate_stats();

可处理 500-490、490-480、... -480 - -490、-490 - -500 的 100 个范围

【讨论】:

    【解决方案3】:

    假设范围有限。

    Select 
    sum(case when val between -140 to -130 then 1 else 0 end) as sum-140_to_-130,
    sum(Case when val between -130 to -120 then 1 else 0 end) as sum-130_to_-140,
    ...
    
    FROM table
    

    如果没有,您可以使用动态 SQL 生成允许多个范围的选择,但是您可能会遇到列限制。

    【讨论】:

      【解决方案4】:

      只需将您想要的范围放入一个表格中,然后使用它来区分值。

      -- SET search_path='tmp';
      
      DROP TABLE measurements;
      
      CREATE TABLE measurements
              ( zval INTEGER NOT NULL PRIMARY KEY
              );
      INSERT INTO measurements (zval)
              SELECT generate_series(1,1000);
      DELETE FROM measurements WHERE random() < 0.20 ;
      
      DROP TABLE ranges;
      CREATE TABLE ranges
              ( zmin INTEGER NOT NULL PRIMARY KEY
              , zmax INTEGER NOT NULL
              );
      INSERT INTO ranges(zmin,zmax) VALUES
      (0, 100), (100, 200), (200, 300),  (300, 400), (400, 500),
      (500, 600), (600, 700), (700, 800),  (800, 900), (900, 1000)
              ;
      
      SELECT ra.zmin,ra.zmax
              , COUNT(*) AS zcount
      FROM ranges ra
      JOIN measurements me
        ON me.zval >= ra.zmin AND me.zval < ra.zmax
      GROUP BY ra.zmin,ra.zmax
      ORDER BY ra.zmin
              ;
      

      结果:

       zmin | zmax | zcount 
      ------+------+--------
          0 |  100 |     89
        100 |  200 |     76
        200 |  300 |     76
        300 |  400 |     74
        400 |  500 |     86
        500 |  600 |     78
        600 |  700 |     75
        700 |  800 |     75
        800 |  900 |     80
        900 | 1000 |     82
      (10 rows)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-02-09
        • 2012-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-27
        • 2013-01-06
        相关资源
        最近更新 更多