SQL按品牌分组取最小最大月份值并计算差值的高效实现
问题解决:按品牌获取最小/最大月份的Value并计算差值
你的原SQL存在逻辑问题:WHERE子句中不能直接使用聚合函数MAX()/MIN(),因为聚合函数是在WHERE过滤完成后才执行计算的,这样写会直接报错。下面提供两种高效的实现方案:
方案一:使用窗口函数(推荐,适配多数现代数据库)
窗口函数只需扫描一次表即可完成标记和计算,在大数据量下性能更优:
WITH brand_month_info AS ( SELECT brand, month, value, -- 标记当前品牌的最小、最大月份 MIN(month) OVER (PARTITION BY brand) AS min_month, MAX(month) OVER (PARTITION BY brand) AS max_month FROM your_table ) SELECT brand, -- 提取最小月份对应的value MAX(CASE WHEN month = min_month THEN value END) AS min_month_value, -- 提取最大月份对应的value MAX(CASE WHEN month = max_month THEN value END) AS max_month_value, -- 计算差值 MAX(CASE WHEN month = max_month THEN value END) - MAX(CASE WHEN month = min_month THEN value END) AS value_diff FROM brand_month_info GROUP BY brand;
如果同一品牌同一月份有多条记录,且你需要取该月份的value聚合值(比如求和/平均),只需把MAX()换成对应的聚合函数即可。
方案二:子查询关联(适合不支持窗口函数的旧版数据库)
先通过子查询获取每个品牌的最小、最大月份,再关联原表拿到对应value:
SELECT base.brand, min_val.value AS min_month_value, max_val.value AS max_month_value, max_val.value - min_val.value AS value_diff FROM ( -- 先拿到每个品牌的最小、最大月份 SELECT brand, MIN(month) AS min_month, MAX(month) AS max_month FROM your_table GROUP BY brand ) base -- 关联最小月份的value JOIN your_table min_val ON base.brand = min_val.brand AND base.min_month = min_val.month -- 关联最大月份的value JOIN your_table max_val ON base.brand = max_val.brand AND base.max_month = max_val.month;
注意:如果同一品牌的同一月份存在多条记录,这个方法会返回重复行,此时需要在关联时对value做聚合(比如SELECT MIN(value) FROM your_table ...)。
内容的提问来源于stack exchange,提问作者sopL
相关产品推荐
相关产品推荐

