web-dev-qa-db-ja.com

「Partition By」または「Max」の使用方法

次のテーブル(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


この結果テーブルは結合で使用されることに注意してください。

20
Stef Heyenrath
select year, x,y
from (
      select year, x, y, max(year) over(partition by x) max_year
      from my data
      )
where  year = max_year
24
schurik
select * from (
  select year, x, y, row_number() over (partition by x order by year desc ) rn 
  from my_data
) where rn = 1
12
Frank Schmitt

他のソリューションよりもはるかに簡単です。

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

また、ポータブルで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
Benoit

ゲイリー・マイヤーズ、たとえば、値Aの場合、年が2010より小さく、その年に最大値がある場合、ソリューションは機能しません。 (たとえば、行2005、A、50が存在する場合)正しいソリューションを取得するには、以下を使用します。 (値を交換するだけです)

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

共通テーブル式(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
Artyom
select year, x, y 
 from my_data stable 
where stable.year = (select max(year) 
                     from my_data tables 
                     where tables.x = stable.x);
0
minglotus
  -- 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
Yordan Georgiev