sql - 在 Postgress 中分桶
问题描述
我应该如何根据销售额存储我的数据?如果没有销售属于特定的桶,那么它应该包含 NA。输出必须包含所有桶,即使它们是空的。对于桶的形成,不使用 CASE 或分支语句。是否可以使用 CTE 或联接或嵌套进行分桶?例如,样本数据为:
表格1
ID | 销售量 |
---|---|
1 | 4 |
2 | 5 |
3 | 10 |
4 | 22 |
5 | 6 |
输出必须是这样的:
桶 | ID | 销售量 |
---|---|---|
1-5 | 1 | 4 |
1-5 | 2 | 5 |
6-10 | 5 | 6 |
6-10 | 3 | 10 |
11-15 | 不适用 | 不适用 |
16-20 | 不适用 | 不适用 |
21-25 | 4 | 22 |
解决方案
您可以定义存储桶并使用left join
:
select b.name, t1.id, count(t1.id) as num_sales
from (select '1-5' as name, 1 as lo, 5 as hi union all
select '6-10' as name, 6 as lo, 10 as hi union all
select '11-15' as name, 11 as lo, 15 as hi union all
select '16-20' as name, 16 as lo, 20 as hi union all
select '21-25' as name, 21 as lo, 25 as hi
) b left join
table1 t1
on t1.sales >= b.lo and t1.sales <= b.hi
group by b.name, t1.id
order by min(lo);
以上应该适用于几乎任何数据库。在 Postgres 中,您可以将其简化为:
select b.name, t1.id, count(t1.id) as num_sales
from (values ('1-5', 1, 5),
('6-10', 6, 10),
('11-15', 11, 15),
('16-20', 16, 20),
('21-25', 21, 25)
) b left join
table1 t1
on t1.sales >= b.lo and t1.sales <= b.hi
group by b.name, t1.id
order by min(lo);
如果垃圾箱的大小都相同,您还可以使用generate_series()
.
推荐阅读
- server - Tornado:如何让它捕捉对 JavaScript 所做的更改?
- java - Python 等价于 Java 正则表达式报价
- python - 了解 Django 中的装饰器
- sql - 使用从一个商店到第二个商店的表类型
- php - AWS cloud9 中的 php.ini 文件
- java - 为什么使用部署在 Tomcat 8 上的 Jersey REST Web 服务的 XML 响应会随着负载的增加而花费更多时间
- android - Android Studio 3.1 设计预览未显示任何内容(按钮、文本等)
- html - CSS帮助:活动按钮不改变样式
- apache-spark - StandardScaler in Spark not working as expected
- c# - SQL 表到类