【问题标题】:How do I use max() in sql如何在 sql 中使用 max()
【发布时间】:2011-09-30 21:07:32
【问题描述】:

我有一张如下所示的表格:

col1   col2  col3  
------ ----- ----- 
A      1     trout
A      2     trout
B      1     bass
C      1     carp
C      2     tuna
D      1     salmon

我真的只想选择 col2 的最大值的行。

我要生成的查询将返回以下内容:

col1   col2  col3  
------ ----- ----- 
A      2     trout
B      1     bass
C      2     tuna
D      1     salmon

我尝试过这样的事情:

select col1, max (col2) as mCol2, col3
from mytable
group by col1, col2

在这种情况下,我得到:

col1   Mcol2 col3  
------ ----- ----- 
A      2     trout
B      1     bass
C      1     carp
C      2     tuna
D      1     salmon

如你所见,我仍然得到C, 1, carp,而我只想要C, 2, tuna

我考虑过尝试做类似的事情

select col1, col2, col3
from mytable
where 
    col1-n-col2 in (
        select col1, max (col2) as mCol2
        from mytable)
group by col1, col2

但我认为这在 SQL 中是不合法的。我错过了什么明显的解决方案?

【问题讨论】:

    标签: sql oracle greatest-n-per-group


    【解决方案1】:

    如果 (col1, col2) 是唯一的,或者您不介意在 tie 的情况下重复:

    SELECT T1.col1, T1.col2, T1.col3
    FROM mytable T1
    JOIN (
        SELECT col1, MAX (col2) AS mCol2
        FROM mytable
        GROUP BY col1
    ) T2
    ON T1.col1 = T2.col1
    AND T1.col2 = T2.mCol2
    

    如果您想在平局的情况下选择任意行(需要 ROW_NUMBER 支持,即不是 MySQL):

    SELECT col1, col2, col3
    FROM (
         SELECT
             col1, col2, col3,
             ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col2 DESC) AS rn
         FROM mytable
    ) T1
    WHERE rn = 1
    

    【讨论】:

      【解决方案2】:

      到目前为止,分析函数是解决此类问题的最佳方法,因为它们比对大型数据集的子查询执行得更好。

      要么尝试 Mark Byers 提供的第二个查询,要么尝试如下所示的查询:

      select 
        col1, 
        max (col2) as mCol2, 
        max (col3) keep (dense_rank last order by col2) as col3
      from mytable
      group by col1
      

      这使用LAST analytic function 在按 col2 排序后获取每个组中的最后一个值。用于 col3 的MAX 是语法所必需的,但实际上只是一个决胜局。

      【讨论】:

      • +1 是这里的最佳答案。虽然你在这里根本没有使用分析函数,只是聚合函数......
      • @RobvanWijk 我意识到我在提交答案之前使用了一个聚合函数,它似乎比改变它更麻烦(尽管我现在正在写一个长评论来证明它的合理性...... )。对我来说,分析是解决大多数问题的最佳方式,我经常在分析和聚合表单中使用 first 和 last 函数。
      【解决方案3】:

      你很亲密

      select t.col1, t.col2, t.col3
      from mytable t,
          (select col1, 
              max (col2) as mx 
          from mytable
          group by col1) m
      where m.col1 = t.col1
      and m.mx = t.col2
      

      【讨论】:

        【解决方案4】:

        您没有指定您使用的哪个数据库 - 在 SQL Server 和其他一些数据库上,您可以使用带有窗口函数的 CTE(通用表表达式)来获取您的行:

        ;WITH HighestOnly AS
        (
           SELECT
               col1, col2, col3,
               ROW_NUMBER() OVER(PARTITION BY col1 ORDER BY col2 DESC) AS 'RowNum'
           FROM 
               MyTable
        ) 
        SELECT 
           col1, col2, col3
        FROM
           HighestOnly
        WHERE 
           RowNum = 1
        

        这将按照指定的标准 (col1) 对您的数据进行“分区”,并为每个数据分区分配连续的数字,从一个开始 - 按给定的第二个标准 (col2 DESC) 排序。因此,对于数据的每个“分区”,col2 中具有最高值的行将具有RowNum = 1 - 这就是我在这里选择的内容。

        【讨论】:

          【解决方案5】:

          这是一种方法

          With max_qry as
          (select col1, max(col2) as mcol2 from mytable group by col1)
          select m.col1, m.col2, m.col3
          from mytable m join max_qry on m.col1 = mq.col1 and m.col2 = mq.mcol2
          

          【讨论】:

            【解决方案6】:

            试试

                select mytable.col1, mytable.col2, mytable.col3
                from mytable
                join 
                 ( select col1, max(col2) as col2
                   from mytable 
                   group by col1) as mytablemax
                on  mytable.col1 = mytablemax.col1 
                and mytable.col2 = mytablemax.col2
            

            【讨论】:

              【解决方案7】:

              嘿嘿..

              我没有安装 Oracle 数据库,但对于 MySQL,这是错误的..

              这是因为你的语法空间......正确的版本是

              SELECT MAX(column) ...
              

              而不是

              SELECT MAX (column) ...
              

              我不认为空间被认为是一种功能......

              【讨论】:

                猜你喜欢
                • 2022-01-13
                • 1970-01-01
                • 2021-12-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多