【问题标题】:Select Rows with Maximum Column Value group by Another Column按另一列选择具有最大列值组的行
【发布时间】:2009-09-15 05:18:44
【问题描述】:

这应该是一个简单的问题,但我无法让它工作:(

如何选择列值最大的行,按另一列分组?

例如,

我有如下表定义:

ID
Del_Index
docgroupviewid

现在的问题是我想先按docgroupviewid 对结果进行分组,然后从每个docgroupviewid 组中选择一行,具体取决于哪一行具有最高的del_index

我试过了

SELECT docgroupviewid, max(del_index),id FROM table
group by docgroupviewid

但是,它不是以正确的id 返回我,而是以相同docgroupviewid 的组中最早的id 返回我。

有什么想法吗?

【问题讨论】:

  • 当有 2 个以上的 del_index 值与同一 docgroupviewid 的最大值匹配时,您如何打破平局?
  • 不确定...你有什么想法吗?
  • 经典例子。困扰我太多次了!!

标签: sql mysql


【解决方案1】:

我自己也曾为此苦苦挣扎过很多次,解决办法就是以不同的方式考虑您的查询。

我想要每个 DocGroupViewID 行,其中 Del_Index 是具有该 DocGroupViewID 的所有行的最高(最大值):

SELECT
    T.DocGroupViewID,
    T.Del_Index,
    T.ID
FROM MyTable T
WHERE T.Del_Index = (
    SELECT MAX( T1.Del_Index ) FROM MyTable T1
    WHERE T1.DocGroupViewID = T.DocGroupViewID 
)

当多行可以有相同的Del_Index 时,情况会变得更加复杂,因为那时您需要某种方式来选择显示哪一个。


编辑:想跟进另一个选项

您可以使用带有 CTE 的 RANK()ROW_NUMBER() 函数来更好地控制结果,如下所示:

-- fake a source table
DECLARE @t TABLE (
    ID int IDENTITY(1,1) PRIMARY KEY,
    Del_Index int,
    DocGroupViewID int
)

INSERT INTO @t
SELECT 1, 1 UNION ALL
SELECT 2, 1 UNION ALL
SELECT 3, 1 UNION ALL
SELECT 1, 2 UNION ALL
SELECT 2, 2 UNION ALL
SELECT 2, 2 UNION ALL
SELECT 1, 3 UNION ALL
SELECT 2, 3 UNION ALL
SELECT 3, 3 UNION ALL
SELECT 4, 3

-- show our source
SELECT * FROM @t

-- select using RANK (can have duplicates)
;WITH cteRank AS
(
    SELECT
        DocGroupViewID,
        Del_Index,
        ID,
        RANK() OVER
            (PARTITION BY DocGroupViewID ORDER BY Del_Index DESC)
        AS RowRank,
        ROW_NUMBER() OVER
            (PARTITION BY DocGroupViewID ORDER BY Del_Index DESC)
        AS RowNumber
    FROM @t
)
SELECT *
FROM cteRank
WHERE RowRank = 1

-- select using ROW_NUMBER
;WITH cteRowNumber AS
(
    SELECT
        DocGroupViewID,
        Del_Index,
        ID,
        RANK() OVER
            (PARTITION BY DocGroupViewID ORDER BY Del_Index DESC)
        AS RowRank,
        ROW_NUMBER() OVER
            (PARTITION BY DocGroupViewID ORDER BY Del_Index DESC)
        AS RowNumber
    FROM @t
)
SELECT *
FROM cteRowNumber
WHERE RowNumber = 1

如果您有办法整理平局,只需将其添加到ORDER BY

【讨论】:

  • 感谢蒂姆的好榜样。
【解决方案2】:

您将不得不稍微复杂化您的查询:

select a.docgroupviewid, a.del_index, a.id from table a
    where a.del_index = (select max(b.del_index) from table
        where b.docgroupviewid = a.docgroupviewid)

【讨论】:

    猜你喜欢
    • 2013-08-15
    • 2021-10-04
    • 1970-01-01
    • 2020-07-11
    • 1970-01-01
    • 2018-08-25
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多