MySQL:使用每列的前3个值打印行的名称

时间:2015-07-07 10:16:08

标签: mysql

+-----------------------------+------+------+------+
| State                       | 2006 | 2007 | 2008 |
+-----------------------------+------+------+------+
| Andaman and Nicobar Islands |   32 |   27 |   23 |
| Andhra Pradesh              | 3824 | 2432 | 1591 |
| Arunachal Pradesh           |   12 |    9 |   25 |
| Assam                       |  617 |  319 |  530 |
| Bihar                       | 1665 | 1949 | 1944 |
| Chandigarh                  |    0 |    5 |    4 |
| Chhattisgarh                |  374 |  401 |  855 |
| Dadra and Nagar Haveli      |    0 |    0 |    0 |
| Daman and Diu               |    2 |    0 |    1 |
| Delhi                       |    0 |    0 |    0 |
| Goa                         |   72 |    1 |   42 |
| Gujarat                     | 2038 |  328 |  540 |
| Haryana                     |  350 |  520 |  427 |
| Himachal Pradesh            |  323 |  214 |   34 |

我有类似的表,只有更多行。列中描述了给定年份的事故数量。我需要打印前3个州,每年的事故数量最多。有没有办法一次性完成? 目前,我只能做到这一年:

SELECT State AS 'Accidents-2006' 
FROM accidents 
ORDER BY `2006` 
DESC LIMIT 3;

然后重复2007和2008年。

编辑:我正在搜索这样的输出:

+-----------------+-----------------+--------------------+
| 2006            | 2007            | 2008               |
+-----------------+-----------------+--------------------+
| Andhra Pradesh  | Andhra Pradesh  | Bihar              |
| Gujarat         | Bihar           | Andhra Pradesh     |
| Bihar           | Haryana         | Chhattisgarh       |

2 个答案:

答案 0 :(得分:1)

注意:可能应该是评论但不足以评论。

我个人将其更改为3(4个ID)列表,其中包含:

State                        | Year | Accidents
Andaman and Nicobar Islands  | 2006 | 32
Andaman and Nicobar Islands  | 2007 | 27

这对于将来验证数据会更容易,因为您不需要编辑结构来添加另一年的数据,并且还可以帮助您按照您想要的方式排列数据。

答案 1 :(得分:1)

您的表有一些严重的规范化问题。

话虽如此,如果重构您的表架构不适合您,这里有一种方法可以使用变量获取所需的结果集:

SELECT `Y2006`, `Y2007`, `Y2008`
FROM (
  SELECT State AS `Y2006`, @rn1:=@rn1+1 AS rn1
  FROM mytable
  CROSS JOIN (SELECT @rn1:=0) AS v
  ORDER BY `2006` DESC LIMIT 3 
) t1
LEFT JOIN (  
   SELECT State AS `Y2007`, @rn2:=@rn2+1 AS rn2
   FROM mytable
   CROSS JOIN (SELECT @rn2:=0) AS v
   ORDER BY `2007` DESC LIMIT 3 
) t2 ON t1.rn1 = t2.rn2   
LEFT JOIN (
   SELECT State AS `Y2008`, @rn3:=@rn3+1 AS rn3
   FROM mytable
   CROSS JOIN (SELECT @rn3:=0) AS v
   ORDER BY `2008` DESC LIMIT 3
) t3 ON t2.rn2 = t3.rn3 

Demo here