如何获取具有第二高值的所有行

时间:2016-07-19 17:26:44

标签: mysql sql

我有以下表格:

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),因为该解决方案已经投入使用。

请帮忙吗?

4 个答案:

答案 0 :(得分:3)

在MySQL中解决每组n的一种方法是模拟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的变量设置为1或@rn + 1,具体取决于是否@prev = t.Name并返回@rn的值作为列rn
  • @prev:=t.name将@prev的值设置为name
  • 的当前值

如果你跑

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

包装到子查询中,rn=2的过滤为您提供了所需的结果

答案 1 :(得分: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 ;

答案 2 :(得分:0)

试试这个:

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

答案 3 :(得分:0)

如果您将其重写为连接,它应该可以工作:

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