次のテーブル(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
この結果テーブルは結合で使用されることに注意してください。
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
他のソリューションよりもはるかに簡単です。
SELECT x, max(year), MAX(y) KEEP (DENSE_RANK FIRST ORDER BY year DESC)
FROM table
GROUP BY x
また、ポータブルで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
ゲイリー・マイヤーズ、たとえば、値Aの場合、年が2010より小さく、その年に最大値がある場合、ソリューションは機能しません。 (たとえば、行2005、A、50が存在する場合)正しいソリューションを取得するには、以下を使用します。 (値を交換するだけです)
SELECT x, max(y), MAX(year) KEEP (DENSE_RANK FIRST ORDER BY y DESC)
FROM test
GROUP BY x
共通テーブル式(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
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 )