SQL Server中按月份获取最高价格对应行数据的查询报错解决求助
解决SQL Server中按月份取价格最高行的问题
嘿,这个问题我经常碰到,咱们一步步来搞定它~
首先得搞清楚你之前的SQL为什么报错:
Select month, segment_id, max(price) as MaxPrice from a
SQL Server的GROUP BY规则很严格——SELECT里的列要么是聚合函数(比如MAX()),要么必须出现在GROUP BY子句里。你只按month分组,但segment_id既不在GROUP BY里,也没被聚合,数据库根本不知道该给每个月返回哪个segment_id,所以就报错了。
接下来给你几个靠谱的解决方案,都是SQL Server里常用的:
方案1:用窗口函数(最推荐,逻辑清晰)
用ROW_NUMBER()窗口函数给每个月份的行按价格降序排名,然后取排名第一的行:
WITH ranked_monthly_prices AS ( SELECT month, segment_id, price, -- 按月份分组,价格降序排,每个组里最高价格的行rank_num=1 ROW_NUMBER() OVER (PARTITION BY month ORDER BY price DESC) AS rank_num FROM a ) SELECT month, segment_id, price FROM ranked_monthly_prices WHERE rank_num = 1;
如果同一个月份里有多个行价格并列最高,你想把这些行都返回的话,把ROW_NUMBER()换成RANK()就行,它会给并列的行相同的排名。
方案2:子查询+JOIN(兼容性好)
先查出每个月的最高价格,再和原表关联找到对应的完整行:
SELECT a.month, a.segment_id, a.price FROM a INNER JOIN ( -- 先得到每个月的最高价格 SELECT month, MAX(price) AS max_price FROM a GROUP BY month ) AS monthly_max ON a.month = monthly_max.month AND a.price = monthly_max.max_price;
这个方法的好处是在老版本的SQL Server里也能跑,同样,如果有并列最高价的行,会返回所有符合条件的行。
方案3:TOP 1 WITH TIES(简洁写法)
用TOP 1 WITH TIES结合窗口函数,一行代码搞定:
SELECT TOP 1 WITH TIES month, segment_id, price FROM a ORDER BY ROW_NUMBER() OVER (PARTITION BY month ORDER BY price DESC);
这个写法和方案1的效果完全一样,就是更紧凑,适合快速写查询。
这几个方法都能得到你想要的结果,个人最推荐方案1,因为逻辑一目了然,后续维护也方便~
内容的提问来源于stack exchange,提问作者michael donte
相关产品推荐
相关产品推荐

