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根据一列中的最大值从多列中选择不同的行的主要内容,如果未能解决你的问题,请参考以下文章