J'ai le tableau suivant (my_data):
year | X | Y
-----+-----+-----
2010 | A | 10
2011 | A | 20
2011 | B | 99
2009 | C | 30
2010 | C | 40
quelle est la meilleure/la plus petite des instructions SQL pour récupérer uniquement les données relatives à l'année la plus élevée et regroupées par 'X', comme ceci:
year | X | Y
-----+-----+-----
2011 | A | 20
2011 | B | 99
2010 | C | 40
Notez que cette table de résultats sera utilisée dans une jointure.
select year, x,y
from (
select year, x, y, max(year) over(partition by x) max_year
from my data
)
where year = max_year
select * from (
select year, x, y, row_number() over (partition by x order by year desc ) rn
from my_data
) where rn = 1
C'est beaucoup plus simple que les autres solutions:
SELECT x, max(year), MAX(y) KEEP (DENSE_RANK FIRST ORDER BY year DESC)
FROM table
GROUP BY x
Vous pouvez également être portable et utiliser un 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
Gary Myers, votre solution ne fonctionne pas si, par exemple, pour la valeur A, l'année est plus petite que 2010 et cette année a une valeur maximale. (Par exemple, si la ligne 2005, A, 50 existait) Pour obtenir la solution correcte, utilisez ce qui suit. (qui échange juste les valeurs)
SELECT x, max(y), MAX(year) KEEP (DENSE_RANK FIRST ORDER BY y DESC)
FROM test
GROUP BY x
Vous pouvez utiliser une expression de table commune (CTE), fonctionne également avec les lignes dupliquées (si nécessaire) Le plan d'exécution est identique, plus ou moins
;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
select year, x, y
from my_data stable
where stable.year = (select max(year)
from my_data tables
where tables.x = stable.x);
-- 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 )