如何使用“Partition By”或“Max”?

时间:2011-06-01 08:30:38

标签: sql oracle max

我有下表(my_data):

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


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

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


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

11 个答案:

答案 0 :(得分:24)

select year, x,y
from (
      select year, x, y, max(year) over(partition by x) max_year
      from my data
      )
where  year = max_year

答案 1 :(得分:12)

select * from (
  select year, x, y, row_number() over (partition by x order by year desc ) rn 
  from my_data
) where rn = 1

答案 2 :(得分:3)

你也可以携带并使用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

答案 3 :(得分:3)

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

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

您可以使用公用表表达式(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

答案 6 :(得分:0)

select year, x, y 
 from my_data stable 
where stable.year = (select max(year) 
                     from my_data tables 
                     where tables.x = stable.x);

答案 7 :(得分:0)

  -- 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 )

答案 8 :(得分:0)

您可以通过在条件中使用子查询来为每个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更快。

答案 9 :(得分:-2)

这也可以是解决方案

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

答案 10 :(得分:-3)

最简单的是

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

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