我正在使用SQL Server,并且有一个表“ a”
month segment_id price
-----------------------------
1 1 100
1 2 200
2 3 50
2 4 80
3 5 10
我想查询一个显示原始列的价格为每月最高价格的
结果应为:
month segment_id price
----------------------------
1 2 200
2 4 80
3 5 10
我试图编写SQL代码:
Select
month, segment_id, max(price) as MaxPrice
from
a
但我遇到了错误:
segment_id 列在选择列表中无效,因为它没有包含在聚合函数或 GROUP BY子句
中>
我尝试了多种修复方式,但是没有找到解决方法
感谢您的帮助,
约翰
答案 0 :(得分:3)
因为您需要一个没有segment_id的group by子句
Select month, max(price) as MaxPrice
from a
Group By month
根据需要每月获得结果,并且segment_id在原始的select语句中未汇总。
如果要使用segment_id,并且每行每个月的最高价格都在重复,则需要使用max()函数作为窗口分析函数,而无需使用Group by子句
Select month, segment_id,
max(price) over ( partition by month order by segment_id ) as MaxPrice
from a
编辑(由于您上一次编辑了所需的结果)::您还需要一个窗口分析功能row_number()
,就像@Gordon已经提到的那样:
Select month, segment_id, price From
(
Select a.*,
row_number() over ( partition by month order by price desc ) as Rn
from a
) q
Where rn = 1
答案 1 :(得分:1)
我会推荐一个相关的子查询:
select t.*
from t
where t.price = (select max(t2.price) from t t2 where t2.month = t.month);
“规范”解决方案是使用row_number()
:
select t.*
from (select t.*,
row_number() over (partition by month order by price desc) as seqnum
from t
) t
where seqnum = 1;
使用正确的索引,相关子查询通常会表现更好。
答案 2 :(得分:1)
仅因为未提及。
另一个选择是 WITH TIES 子句。
要明确,Gordon和Barbaros的方法可能会提高性能,但是此技术不需要或不会产生额外的列。
Select Top 1 with ties *
From YourTable
Order By row_number() over (partition by month order by price desc)
答案 3 :(得分:0)
使用not exists
:
select t.*
from tablename t
where not exists (
select 1 from tablename
where month = t.month and price > t.price
)
或:
select t.*
from tablename inner join (
select month, max(price) as price
from tablename
group By month
) g on g.month = t.month and g.price = t.price