【问题标题】:Rails SQL - create buckets, and get counts of records in each bucketRails SQL - 创建存储桶,并获取每个存储桶中的记录数
【发布时间】:2015-01-01 23:48:30
【问题描述】:

我有一个 Jobs 表,其中有一列是 salary

如何将工资分成 10,000 美元一组,然后计算每个桶中有多少工作?

最好使用 Rails 活动记录的答案,但考虑到难度,我也会接受原始 SQL 答案。

起始数据

Jobs

id      salary (integer)
-----------------
1       93,530
2       72,400
3       120,403
4       193,001
...

结果数据

bucket               job_count
----------------------------
$0 - $9,999          0
$10,000 - $19,999    0
$20,000 - $29,999    3
$30,000 - $39,999    5
$40,000 - $49,999    12

【问题讨论】:

    标签: sql ruby-on-rails ruby-on-rails-4 rails-activerecord


    【解决方案1】:

    这是另一个基于 SQL 的解决方案。

    像这样获取每个薪水的桶:

    select 
      FLOOR(salary/10000) as bucket
    from jobs
    

    使用GROUP BY 进行计数:

    select 
      bucket, 
      count(*)
    from (
        select FLOOR(salary/10000) as bucket
        from jobs
    ) as t1
    GROUP BY bucket
    

    最后,添加范围而不是桶号:

    select 
      CONCAT('$', FORMAT(bucket*10000,0), ' - $', FORMAT((bucket+1)*10000-1,0)) as range, 
      job_count
    from ( 
        select bucket, count(*) as job_count
        from (
            select FLOOR(salary/10000) as bucket
            from jobs
        ) as t1
        GROUP BY bucket
    ) as t2
    

    请注意,使用的函数是用于 MySQL 的。 YMMV。

    【讨论】:

    • 请注意,这可能会遗漏空范围。
    【解决方案2】:

    从 SQL 的角度来看,有几种方法。这是一个。

    -- First, create a report table (temporarily here, but could be permanent):
    
    create table salary_report (
      bucket      integer,
      lower_limit integer,
      upper_limit integer,
      job_count   integer
    );
    
    -- populate the table
    -- note this could (and probably should) be automated, not hardcoded
    insert into salary_report values (1,00000,09999,0);
    insert into salary_report values (2,10000,19999,0);
    insert into salary_report values (3,20000,29999,0);
    insert into salary_report values (4,30000,39999,0);
    insert into salary_report values (5,40000,49999,0);
    
    -- set correct counts
    update salary_report as sr
      set job_count = (
        select count(*)
        from jobs as j
        where j.salary between sr.lower_limit and sr.upper_limit
        );
    
    -- finally, access the data (through activerecord?)
    -- note: not formatted as dollar amounts
    select concat( sr.lower_limit,' - ',sr.upper_limit) as range, job_count, bucket
    from salary_report
    order by bucket;
    
    -- drop table if required
    drop table salary_report;
    

    我已尝试保持 SQL 的通用性,但 具体语法可能因您的 RDBMS 而异。 没有提供 SQL Fiddle,因为它今天似乎坏了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-31
      • 1970-01-01
      • 1970-01-01
      • 2019-12-27
      • 2020-02-11
      • 1970-01-01
      • 1970-01-01
      • 2019-05-14
      相关资源
      最近更新 更多