如何解决如何在SQL Server 2012中的列中查找最大值
我想在列中找到最大值
ID CName Tot_Val PName
--------------------------------
1 1 100 P1
2 1 10 P2
3 2 50 P2
4 2 80 P1
以上是我的表格结构。我只想从表中找到最大总价值。因为四个行ID 1和2在CName
中具有相同的值,但总val和PName
具有不同的值。我期望的是必须找到ID 1和2中的最大值
预期结果:
ID CName Tot_Val PName
--------------------------------
1 1 100 P1
4 2 80 P1
我需要与上述相同的结果
select Max(Tot_Val),CName
from table1
where PName in ('P1','P2')
group by CName
这是我尝试过的查询,但是我的问题是我无法在此表中使用PName。如果我在选择列表中添加PName意味着它将显示加倍的行,例如结果是100行,但是当我在所选列表中添加PName并按列表分组时,它将显示600行。那是问题。
有人可以帮我解决这个问题吗?
解决方法
一个可能的选择是使用子查询。给每行一个由CName
排序的Tot_Val
组内的数字。然后选择行号等于一的行。
select x.*
from ( select mt.ID,mt.CName,mt.Tot_Val,mt.PName,row_number() over(partition by mt.CName order by mt.Tot_Val desc) as No
from MyTable mt ) x
where x.No = 1;
一种替代方法是使用公用表表达式(CTE)而不是子查询来隔离第一个结果集。
with x as
(
select mt.ID,row_number() over(partition by mt.CName order by mt.Tot_Val desc) as No
from MyTable mt
)
select x.*
from x
where x.No = 1;
查看this fiddle中的两种解决方案。
,您可以在每个组的前n个搜索中进行搜索。
有两种常见的实现方法。最有效的方法取决于您的索引和数据分布,以及是否已经有了包含所有CName
值列表的另一个表。
- 使用
ROW_NUMBER
WITH
CTE
AS
(
SELECT
ID,CName,Tot_Val,PName,ROW_NUMBER() OVER (PARTITION BY CName ORDER BY Tot_Val DESC) AS rn
FROM table1
)
SELECT
ID,PName
FROM CTE
WHERE rn=1
;
- 使用
CROSS APPLY
WITH
CTE
AS
(
SELECT CName
FROM table1
GROUP BY CName
)
SELECT
A.ID,A.CName,A.Tot_Val,A.PName
FROM
CTE
CROSS APPLY
(
SELECT TOP(1)
table1.ID,table1.CName,table1.Tot_Val,table1.PName
FROM table1
WHERE
table1.CName = CTE.CName
ORDER BY
table1.Tot_Val DESC
) AS A
;
在dba.se Retrieving n rows per group 或此处Get top 1 row of each group 上查看非常详细的答案。
, CROSS APPLY
可能与相关子查询一样快,但这通常具有非常好的性能(并且比ROW_NUMBER()
更好:
select t.*
from t
where t.tot_val = (select max(t2.tot_val)
from t t2
where t2.cname = t.cname
);
注意:性能取决于在(cname,tot_val)
上有一个索引。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。