Как использовать «Partition By» или «Max»? - PullRequest
20 голосов
/ 01 июня 2011

У меня есть следующая таблица (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

Обратите внимание, что эта таблица результатов будет использоваться в объединении.

Ответы [ 10 ]

24 голосов
/ 01 июня 2011
select year, x,y
from (
      select year, x, y, max(year) over(partition by x) max_year
      from my data
      )
where  year = max_year
12 голосов
/ 01 июня 2011
select * from (
  select year, x, y, row_number() over (partition by x order by year desc ) rn 
  from my_data
) where rn = 1
3 голосов
/ 01 июня 2011

Это намного проще, чем другие решения:

SELECT x, max(year), MAX(y) KEEP (DENSE_RANK FIRST ORDER BY year DESC)
  FROM table
  GROUP BY x
3 голосов
/ 01 июня 2011

Вы также можете быть портативным и использовать 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
1 голос
/ 08 июля 2015

Вы можете использовать общее табличное выражение (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
1 голос
/ 22 сентября 2014

Гэри Майерс, ваше решение не работает, если, например, для значения A год меньше, чем 2010, и этот год имеет максимальное значение.(Например, если существовала строка 2005, A, 50). Чтобы получить правильное решение, используйте следующее.(который просто меняет значения)

SELECT x, max(y), MAX(year) KEEP (DENSE_RANK FIRST ORDER BY y DESC)
FROM test
GROUP BY x
0 голосов
/ 02 августа 2017

это также может быть решением

выберите наибольшее ((e), (g), (c), (a), (b)) как последнюю дату из abc

0 голосов
/ 23 июля 2015
  -- 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 )
0 голосов
/ 16 июня 2015
select year, x, y 
 from my_data stable 
where stable.year = (select max(year) 
                     from my_data tables 
                     where tables.x = stable.x);
0 голосов
/ 01 июня 2011

Самое простое -

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

Это может вызвать сканирование таблицы, если нет индекса по году.Но с индексом должно быть перфоманс

...