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

Posted

技术标签:

【中文标题】SQL根据一列中的最大值从多列中选择不同的行【英文标题】:SQL Selecting distinct rows from multiple columns based on max value in one column 【发布时间】:2012-08-14 11:16:59 【问题描述】:

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

ECode SHCode TotalNrShare CountryCode Country 000001 +00010 100 UKI 英国 000001 ABENSO 900 USA 美国 000355 +00012 1000 ESP 西班牙 000355 000010 50 FRA 法国 000042 009999 10 GER 德国 000042 +00012 999 ESP 西班牙 000787 ABENSO 500 USA 美国 000787 000150 500 ITA 意大利 001010 009999 100 GER 德国

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

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

ECode SHCode TotalNrShare CountryCode Country 000001 ABENSO 900 USA 美国 000355 +00012 1000 ESP 西班牙 000042 +00012 999 ESP 西班牙 000787 ABENSO 500 USA 美国 001010 009999 100 GER 德国

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

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

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

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

【问题讨论】:

哪种风格的 SQL? mysql、SQL Server、SQLite、Oracle 等都有不同的功能和不同的语法。另外,您尝试的 sql 查询有什么问题?您是否收到错误消息或“错误”结果?如果是这样,请显示这些错误或错误结果。 如果有任何大师可以帮助我,我将不胜感激! 抱歉,我的一些文字被截断了,它的 SQL Server 2005 【参考方案1】:
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 的不同列表的表。

【讨论】:

谢谢 Dems,我试过了,但每次将代码保存到我的视图时它都会崩溃。它适用于 SQL 2005 吗? (如 SQL Management Studio 崩溃) 在回答您关于我的尝试没有做什么的其他查询时,它没有返回 ECode 的单个实例。我得到多行,我只想要每个 ECode 具有最高 TotalNrShares 的行。我希望我有道理.. @NSP - 是的,它适用于 SQL 2005 及更高版本。如果它崩溃了,请附上错误信息,我会帮你找的。 (注意:如果WITH 之前有任何语句,那么它们必须; 结束。因此,许多人经常将; 放在WITH 之前时间,以防万一。) Thnx Dems,我正在尝试用您上面的示例替换我的查询,当我将其应用于现有视图时,程序崩溃,每次都没有错误。 @NSP 可视化查询设计器仅支持非常简单的查询,如果您尝试使用此定义创建新视图,只需在 CREATE VIEW ... 标题下的新查询窗口中运行即可。【参考方案2】:

试试这个;

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

【讨论】:

谢谢 Joe G Joseph,我也试过你的代码。当我试图将您的示例保存在我的视图中时,SQL Management Studio (2005) 再次崩溃。我不确定我做错了什么还是不兼容? 我试过你的代码谢​​谢,但我没有返回 TotalNrShares 列中值最高的行。我抽查发现一个 ECode 有两行,它返回 TotalNrShares 中值最低的行。

以上是关于SQL根据一列中的最大值从多列中选择不同的行的主要内容,如果未能解决你的问题,请参考以下文章

SQL:根据另一列的值在列上保留一个具有最大值的行

根据熊猫中多列的条件(最大值)替换列中的值

基于sql中另一列的一列中的最大数据

从具有联合的两个表中选择一列中最大值的所有行

如何在一列中获得不同的多列行

如何获取熊猫数据框中的行,列中具有最大值并保留原始索引?