即使该桶中的项目计数为0,如何使用case语句保留存储桶?

时间:2016-11-14 22:40:37

标签: sql

以下是我为此问题创建的名为“ Salary_table ”的数据表: enter image description here

所以我想找到每个部门每个工资桶中的员工人数。桶是

"<$100" "$100-$200" and ">$200"

所需的输出是:

enter image description here

以下是我完成此任务的代码:

select distinct(st.department) as "Department", 
sb.salary_bucket as "salary range", count(*)
from Salary_table st
Left join (
    select department, employee, case
        when salary < 100 then "<$100"
        when salary between 100 and 200 then "$100-$200"
        else ">$200"
        end 
        as salary_bucket
    from Salary_table
) sb
on sb.employee = st.employee
group by st.department, sb.salary_bucket
order by st.department, sb.salary_bucket
;

但我的输出有点不足以期待:

enter image description here

我目前的输出存在两个问题:

  1. 0名员工在桶范围内获得工资的桶没有列出;我希望它以值“0”
  2. 列出
  3. 工资桶的顺序不正确,即使我在声明中添加了“order by”,但我认为这是b / c的文本所以不能真正做到这一点。
  4. 我真的很感激如何解决/实现上面提到的这两个问题的一些提示和指示。非常感谢你!

    我尝试了什么

    1. 我尝试使用“左连接”,但输出结果相同
    2. 我尝试添加“order by”子句,但似乎不适用于文本存储桶

1 个答案:

答案 0 :(得分:1)

你有点走上正轨,但这个想法有点复杂。使用cross join获取所有行 - 存储桶和部门。然后使用left join引入匹配信息,最后使用group by进行聚合:

select d.department, b.salary_bucket,
       count(sb.department) as cnt
from (select '<$100' as salary_bucket union all
      select '$100-$200' union all
      select '>$200'
     ) b cross join
     (select distinct department from salary_table
     ) d left join
     (select department, employee,
             (case when salary < 100 then '<$100'
                   when salary between 100 and 200 then '$100-$200'
                   else '>$200'
              end) as salary_bucket
      from Salary_table
     ) sb
     on sb.department = d.department and
        sb.salary_bucket = b.salary_bucket
group by d.department, b.salary_bucket;