【问题标题】:How to use "Partition By" or "Max"?如何使用“Partition By”或“Max”?
【发布时间】:2011-09-06 02:24:00
【问题描述】:

我有下表(my_data):

year |  X  |  Y
-----+-----+-----
2010 |  A  |  10
2011 |  A  |  20
2011 |  B  |  99
2009 |  C  |  30
2010 |  C  |  40


什么是仅检索与最高年份相关并按 'X' 分组的数据的最佳/最小 SQL 语句,如下所示:

year |  X  |  Y
-----+-----+-----
2011 |  A  |  20
2011 |  B  |  99
2010 |  C  |  40


请注意,此结果表将用于连接。

【问题讨论】:

  • 为什么2009年不是他们的结果????
  • 我忘记包含数据应按“X”列分组的信息。

标签: sql oracle max


【解决方案1】:
select * from (
  select year, x, y, row_number() over (partition by x order by year desc ) rn 
  from my_data
) where rn = 1

【讨论】:

  • 感谢您的回答,它工作正常。但是我确实接受了“shurik”作为答案,因为它更容易理解。
【解决方案2】:

最简单的是

Select * 
from table 
where year = (select max(year) from table)

除非年有索引,否则可能会导致表扫描。但是带索引应该是高性能的

【讨论】:

  • 但这不会按照 OP 的要求返回“C”和 2010 的值。
  • 这不会产生预期的结果
【解决方案3】:
select year, x,y
from (
      select year, x, y, max(year) over(partition by x) max_year
      from my data
      )
where  year = max_year

【讨论】:

【解决方案4】:

您也可以是可移植的并使用 OUTER JOIN :

select t1.year, t1.x, t1.y
  from my_data t1
  left join my_data t2
    on t2.x = t1.x
   and t2.year > t1.year
 where t2.x is null

【讨论】:

    【解决方案5】:

    它比其他解决方案简单得多:

    SELECT x, max(year), MAX(y) KEEP (DENSE_RANK FIRST ORDER BY year DESC)
      FROM table
      GROUP BY x
    

    【讨论】:

      【解决方案6】:

      Gary Myers,您的解决方案不起作用,例如,对于值 A,年份小于 2010 年并且该年份具有最大值。 (例如,如果行 2005,A,50 存在) 为了获得正确的解决方案,请使用以下内容。 (只是交换值)

      SELECT x, max(y), MAX(year) KEEP (DENSE_RANK FIRST ORDER BY y DESC)
      FROM test
      GROUP BY x
      

      【讨论】:

        【解决方案7】:
        select year, x, y 
         from my_data stable 
        where stable.year = (select max(year) 
                             from my_data tables 
                             where tables.x = stable.x);
        

        【讨论】:

        • @Nikolay 似乎您在原始代码中添加了高亮显示。正确的?谢谢
        【解决方案8】:

        您可以使用公用表表达式 (CTE),也可以处理重复的行(如果需要) 执行计划是一样的,或多或少

        ;With my_data_cte as (
            SELECT [year], x,y,ROW_NUMBER() OVER (
                PARTITION BY x
                ORDER BY [year] desc) as rn
        FROM [dbo].[my_data])
        select [year], x,y from my_data_cte 
        where rn = 1
        

        【讨论】:

          【解决方案9】:
          -- I had a slightly different case and just wandering why this one should't work 
          SELECT my_data.x , my_data.y , my_data1.max_year 
          FROM my_data
          INNER JOIN 
          ( 
            SELECT x , max (year ) as max_year
            FROM my_data
            -- WHERE 1=1
            -- AND FILTER1=VALUE1
            GROUP BY my_data.x
          ) my_data1
          ON ( my_data.x = my_data1.x )
          

          【讨论】:

          • 为什么是LEFT JOIN 而不是INNER JOIN?为什么WHERE 1=1?此外,使用连接的效率低于使用MAX(...) KEEP( DENSE_RANK ... )
          • txn 进行更正 => 固定为内部连接 ​​+ 添加了开发用户友好性的 where ...
          【解决方案10】:

          这也可以解决

          从 abc 中选择最大的( (e),(g),(c),(a),(b) ) 作为最新日期

          【讨论】:

          • 感谢您提供此代码 sn-p,它可能会提供一些即时帮助。一个正确的解释would greatly improve 其教育价值通过展示为什么这是一个很好的解决问题的方法,并将使它对未来有类似但不相同的问题的读者更有用。请edit您的答案添加解释,并说明适用的限制和假设。
          【解决方案11】:

          您可以使用条件中的子查询为每个 X 选择最近的年份:

          select a.year, a.x, a.y
          from my_data a
          where
            a.year = (
              select max(a_yr.year) from my_data a_yr
              where a_yr.x = a.x);
          

          数据:

          year |  X  |  Y
          -----+-----+-----
          2010 |  A  |  10
          2011 |  A  |  20
          2011 |  B  |  99
          2009 |  C  |  30
          2010 |  C  |  40
          

          结果:

          year |  X  |  Y  
          -----+-----+-----
          2011 |  A  |  20 
          2011 |  B  |  99 
          2010 |  C  |  40 
          

          根据我有限的测试,这种方法似乎比using partition by更快。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-09-01
            • 2019-09-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-08-06
            相关资源
            最近更新 更多