SQL技术咨询:统计不同价格区间内商品的出现次数
解决SQL价格区间统计问题的查询示例
没问题,我来帮你搞定这个统计需求。首先得处理Table A里那个有点特殊的价格字段——带货币符号的字符串,还存了放大10^7倍的值,所以第一步得把它转换成真实的价格数值,再按区间分组统计。
核心思路分解
- 提取并转换价格:从字符串里剥离数字部分,转成数值后除以10000000得到真实价格。
- 定义价格区间:用
CASE WHEN划分你需要的价格档位。 - 分组统计:按区间分组,计算每个区间的商品数量。
基础查询(仅针对Table A)
如果不需要关联Table B,直接统计所有商品的价格区间分布,用这个查询:
SELECT -- 自定义价格区间,可根据需求调整范围 CASE WHEN CAST(REGEXP_REPLACE(price, '[^0-9]', '') AS DECIMAL) / 10000000 < 100 THEN '0-99' WHEN CAST(REGEXP_REPLACE(price, '[^0-9]', '') AS DECIMAL) / 10000000 BETWEEN 100 AND 499 THEN '100-499' WHEN CAST(REGEXP_REPLACE(price, '[^0-9]', '') AS DECIMAL) / 10000000 BETWEEN 500 AND 999 THEN '500-999' WHEN CAST(REGEXP_REPLACE(price, '[^0-9]', '') AS DECIMAL) / 10000000 >= 1000 THEN '1000+' ELSE '未知价格' END AS price_range, COUNT(*) AS product_count FROM TableA -- 可选:过滤特定kind的商品 -- WHERE kind = 1 GROUP BY price_range ORDER BY -- 保证区间按顺序排列,避免字符串排序混乱 CASE price_range WHEN '0-99' THEN 1 WHEN '100-499' THEN 2 WHEN '500-999' THEN 3 WHEN '1000+' THEN 4 ELSE 5 END;
关联Table B的扩展查询
如果需要结合分类关联关系(比如按分类+价格区间统计),可以这样写:
SELECT B.category_name, -- 假设Table B有分类名字段 CASE WHEN CAST(REGEXP_REPLACE(A.price, '[^0-9]', '') AS DECIMAL) / 10000000 < 100 THEN '0-99' WHEN CAST(REGEXP_REPLACE(A.price, '[^0-9]', '') AS DECIMAL) / 10000000 BETWEEN 100 AND 499 THEN '100-499' WHEN CAST(REGEXP_REPLACE(A.price, '[^0-9]', '') AS DECIMAL) / 10000000 BETWEEN 500 AND 999 THEN '500-999' WHEN CAST(REGEXP_REPLACE(A.price, '[^0-9]', '') AS DECIMAL) / 10000000 >= 1000 THEN '1000+' ELSE '未知价格' END AS price_range, COUNT(*) AS product_count FROM TableA A JOIN TableB B ON A.category_id = B.category_id -- 可选:过滤条件 -- WHERE A.kind = 2 AND B.parent_category_id = 10 GROUP BY B.category_name, price_range ORDER BY B.category_name, CASE price_range WHEN '0-99' THEN 1 WHEN '100-499' THEN 2 WHEN '500-999' THEN 3 WHEN '1000+' THEN 4 ELSE 5 END;
小细节说明
- 价格提取的兼容性:用
REGEXP_REPLACE(price, '[^0-9]', '')是为了适配各种货币符号(比如USD、EUR、CNY等),不管前面的符号是什么,都能提取纯数字。如果你的SQL方言不支持正则(比如老版本MySQL),可以用嵌套REPLACE:REPLACE(REPLACE(A.price, 'USD ', ''), 'EUR ', '')。 - 数值类型选择:用
DECIMAL是为了避免整数溢出,尤其是当原始数字很大的时候,你可以根据真实价格的精度调整,比如DECIMAL(18,2)来保留两位小数。 - 区间排序:最后用
CASE指定排序顺序,不然字符串排序会把"1000+"排在"0-99"前面,结果顺序会乱。
内容的提问来源于stack exchange,提问作者Anton FromButovo
相关产品推荐
相关产品推荐

