2016-07-19 5 views
3

I가이 다음 표 :초 가장 높은 값을 가진 모든 행을 얻는 방법

name value year 
A  1 2015 
A  2 2014 
A  3 2013 
B  1 2015 
B  3 2013 
C  1 2015 
C  2 2014 

하는 방법은 다음과 같이, 각각의 이름, 두 번째로 높은 년과 행에 대해 얻을 수 있습니다 :

name value year 
A  2 2014 
B  3 2013 
C  2 2014 

select name, value, year 
from TABLE_NAME 
WHERE year IN (select year from TABLE_NAME order by year desc limit 1,1) 

이전 쿼리 나에게 오류를 제공합니다 :

나는 다음과 같은 쿼리하지만 성공을 시도 "SQL 오류 (1235) :이 버전의 MySQL은 아직 'LIMIT & IN/ALL/ANY/SOME 하위 쿼리'를 지원하지 않습니다."

그리고 MySQL 버전 (5.6.25) 솔루션이 이미 생산 중이기 때문입니다.

도움이 필요하십니까?

+1

을 서브 쿼리가 실행 한 경우는 올해를'2014' 선택하고 올해'모든 행을 반환 = 2014' – David

답변

3

한 가지 방법은 ROW_NUMBER을 시뮬레이션하는 것입니다. 이 경우 이름 당 하나의 값만 반환됩니다.

SELECT 
    name, 
    value, 
    year 
FROM 
    (SELECT 
     t.name, 
     t.value, 
     t.year, 
     @rn := if(@prev = t.name, @rn + 1,1) as rn, 
     @prev:=t.name 

    FROM 
     test_table as t 
     JOIN (SELECT @Prev:= Null, @Rn := 0) as v 
    ORDER BY 
     t.name, 
     T.year desc) as t 
WHERE 
    rn = 2; 

어떻게 작동합니까?

  • SELECT @Prev:= Null, @Rn := 0은 @Prev와 @Rn의 두 변수를 초기화합니다.
  • @rn := if(@prev = t.name, @rn + 1,1) as rn
  • 는 RN
  • @prev:=t.name 같 @prev의 값을 설정 @prev = t.Name 및 컬럼으로 @rn의 값을 리턴하는 경우에 따라 1 또는 @rn + 1 중 어느 하나에 @rn의 변수를 설정 당신이

    SELECT 
        t.name, 
        t.value, 
        t.year, 
        @prev = t.name as eval, 
        @rn := if(@prev = t.name, @rn + 1,1) as rn, 
        @prev:=t.name as prev 
    
    FROM 
        test_table as t 
        JOIN (SELECT @Prev:= Null, @Rn := 0) as v 
    ORDER BY 
        t.name, 
        T.year desc 
    

    내가 기대하는 뭔가

    name value year eval rn prev 
    A  1 2015 false 1 null 
    A  2 2014 true 2 A 
    A  3 2013 true 3 A 
    B  1 2015 false 1 A 
    B  3 2013 true 2 B 
    C  1 2015 false 1 B 
    C  2 2014 true 2 C 
    
    01,235

    처럼 실행하면 이름

의 현재 값

하위 쿼리로 감싸고 rn=2에 대한 필터링은 원하는 결과를 제공합니다.

+0

그것은 효과가있다! 고마워. – tfcsantana

+0

나는 약간의 솔루션을 압도했다. 어떻게 작동하는지 배울 수 있는가? 다시 한번 감사드립니다. – tfcsantana

+0

@tfcsantana expeline을 추가했습니다. –

0

이 시도 : 당신이 가입으로 재 작성하는 경우

select * from test_table where year = (select distinct year from test_table order by year desc limit 1,1) 
+0

그냥 내부 쿼리에 "distinct"를 추가해야합니다. – Lakhan

0

그것은 작동합니다 : MySQL의에서 그룹 당 N을 해결하기

select b.name, b.value, b.year 
    from (select year 
      from table_name 
     order by year desc 
     limit 1, 1) a 
    join table_name b 
    on b.year = a.year 
+1

"B, 2013"을 반환하지 않을 것이라고 생각합니다. –

+0

@Conrad : He. 네가 옳아. 나는 원하는 결과에주의를 기울이지 않았다. 나는 그의 질문을 다시 썼다. 제대로 쓰지도 않았다. – sstan

1

내 전략은 그룹화를 사용하여 가장 높은 연도를 찾는 것입니다. 그런 다음 원래 테이블과 결합하여 가장 높은 해를 제거하십시오. 마지막으로 각 이름에 대해 두 번째로 높은 해를 찾기 위해 결합 된 테이블을 그룹화하십시오. (당신이 value이 필요하면 당신은 그것을 찾기 위해 원래의 테이블을 가진 INNER JOIN을 할 수 있습니다.)

SELECT name, MAX(year) 
FROM 
    (SELECT name, year 
     FROM TABLE_NAME) AS x1 
    INNER JOIN 
    (SELECT name, MAX(year) AS year 
     FROM TABLE_NAME 
     GROUP BY name, year 
    ) AS x2 
    ON x1.name = x2.name AND x1.year <> x2.year 
GROUP BY name 
ORDER BY name ASC ; 
+1

n 번째 최상위가 n 개의 하위 쿼리를 취할 수도 있지만 ("값"도 원할 경우)이 작업이 가능합니다. 그것은 귀하의 요구 사항에 따라 넥타이의 경우 하나 이상의 기록을 반환하는 장점이 있습니다. –

관련 문제