mysql - 从多列中选择3个最小值

时间:2014-12-07 18:15:28

标签: mysql

ID COL1 COL2 COL3 COL4 COL5 COL6 COL7
-------------------------------------
1   4    13   8    0    9    11   2
2   12   3    3    10   17   12   9
3   17   0    0    19   3    1    3
4   5    0    16   0    9    11   2

这是一个示例数据表。

我需要做的是选择并标记每行中的三个最小值,以便识别每一个。

例如,我想知道在Row2中,三个最小的值是3,3,9并且它们在COL2,COL3,COL7中

我在想我需要合并mysql中提供的LEAST()命令,但它似乎只返回一个值(最小的一个)。

SELECT LEAST(COL1,COL2,COL3,COL4,COL5,COL6,COL7)

我似乎无法弄清楚如何获得3个最小值,而不只是一个。

2 个答案:

答案 0 :(得分:1)

不幸的是你的桌子没有正常化:(

在这种情况下,可能的解决方案是使用如下查询来解开表:

CREATE VIEW unpivoted AS
SELECT id, 'col1' colname, col1 as value FROM Table1
UNION ALL
SELECT id, 'col2' colname, col2 FROM Table1
UNION ALL
SELECT id, 'col3' colname, col3 FROM Table1
UNION ALL
SELECT id, 'col4' colname, col4 FROM Table1
UNION ALL
SELECT id, 'col5' colname, col5 FROM Table1
UNION ALL
SELECT id, 'col6' colname, col6 FROM Table1
UNION ALL
SELECT id, 'col7' colname, col7 FROM Table1

然后使用如下所示的查询来查找3个最小值,然后将结果转回:

SET @x = 0;
Set @lastid = -999;

SELECT id,
       min( IF( x = 0, colname, null )) As Colname1,
       min( IF( x = 0, value, null )) As value1,
       min( IF( x = 1, colname, null )) As Colname2,
       min( IF( x = 1, value, null )) As value2,
       min( IF( x = 2, colname, null )) As Colname3,
       min( IF( x = 2, value, null )) As value3
FROM (
  SELECT id, colname, value,
         IF( @lastid = id, @x:=@x+1,
             IF( (@lastid:=id), @x:=0, @x:=0 ) 
         ) As x
  FROM unpivoted
  ORDER BY id, value
) q
WHERE x < 3
GROUP BY id

演示:http://sqlfiddle.com/#!2/f20ee4/5
但是这些查询的速度将会非常缓慢,甚至不能在大桌子上进行尝试。
您需要规范化表格。

答案 1 :(得分:0)

Kordirko的解决方案可能是最快的方法(每行没有大量的比较逻辑)。但是,在我看来,以下内容更为直观:

select id,
       substring_index(group_concat(colname order by value), ',', 3) as Top3Columns,
       substring_index(group_concat(value order by value), ',', 3) as Top3Values
from unpivoted
group by id;

这将名称和值分别放在一列中,作为连接列表。如果您希望它们位于不同的列中,您可以使用类似的想法。