SQL根据一列中的最大值从多列中选择不同的行

时间:2012-08-14 11:16:59

标签: sql sql-server sql-server-2005

这是我的SQL视图 - 我们称之为MyView:

ECode   SHCode  TotalNrShare    CountryCode Country
000001  +00010  100 UKI United Kingdom
000001  ABENSO  900 USA United States
000355  +00012  1000    ESP Spain
000355  000010  50  FRA France
000042  009999  10  GER Germany
000042  +00012  999 ESP Spain
000787  ABENSO  500 USA United States
000787  000150  500 ITA Italy
001010  009999  100 GER Germany

我想在每个ECode的TotalNrShare列中返回编号最大的单行。

例如,我想从上面的视图中返回这些结果:

ECode   SHCode  TotalNrShare    CountryCode Country
000001  ABENSO  900 USA United States
000355  +00012  1000    ESP Spain
000042  +00012  999 ESP Spain
000787  ABENSO  500 USA United States
001010  009999  100 GER Germany

(注意在ECode 000787的情况下,有两个SHCode,每个500,因为它们的数量相同,我们只能返回第一行而不是两者,对我来说哪一行返回并不重要因为这种情况很少发生,我的分析不需要100%)

我尝试了各种各样的东西,但似乎无法返回unqiue结果或我需要的其他国家/地区代码/国家/地区信息。

这是我的一次尝试(基于此网站上的其他解决方案,但我做错了):

SELECT tsh.ECode, tsh.SHCode, tsh.TotalNrShare, tsh.CountryCode, tsh.Country
FROM  dbo.MyView AS tsh INNER JOIN
                   (SELECT DISTINCT ECode, MAX(TotalNrShare) AS MaxTotalSH
                    FROM   dbo.MyView
                    GROUP BY ECode) AS groupedtsh ON tsh.ECode = groupedtsh.ECode AND tsh.TotalNrShare = groupedtsh.MaxTotalSH

2 个答案:

答案 0 :(得分:2)

WITH
  sequenced_data AS
(
  SELECT
    *,
    ROW_NUMBER() OVER (PARTITION BY ECode ORDER BY TotalNrShare) AS sequence_id
  FROM
    myView
)
SELECT
  *
FROM
  sequenced_data
WHERE
  sequence_id = 1

但是,这应该与示例查询提供相同的结果。这只是一种完成同样事情的不同方法。

然而,正如你所说的那样是错误的,请你详细说明出了什么问题? TotalNrShare实际上是一个字符串吗?这会弄乱你的订单(以及MAX()吗?

修改

即使上面的代码与您的SQL Server不兼容,也不应该完全崩溃。您应该只是收到一条错误消息。例如,尝试执行Select * By Magic,它应该只是给出错误。我强烈建议您查看和/或重新安装Management Studio的安装。

就替代方案而言,你可以这样做......

SELECT
  *
FROM
  (SELECT ECode FROM MyView GROUP BY ECode) AS base
CROSS APPLY
  (SELECT TOP 1 * FROM MyView WHERE ECode = base.ECode ORDER BY TotalNrShare DESC) AS data

理想情况下,您会将base子查询替换为已包含您感兴趣的所有ECode的不同列表的表。

答案 1 :(得分:0)

试试这个;

with cte as( 
 SELECT tsh.ECode, tsh.SHCode, tsh.TotalNrShare, tsh.CountryCode, tsh.Country,
 ROW_NUMBER() over (partition by ECode order by SHCode ) as row_num 
FROM  dbo.MyView)
select * from cte where row_num=1