2015-06-17 25 views
0

我有一个表(让我们称之为mytable)与下面的结构。该表每天记录近100万行。sql:以列格式从表中获取3个最高值

id  date  timestamp licenseid storeid deviceid value 
1  2015-06-12 17:36:15 lic0001  1   0add  52 
2  2015-06-12 17:36:15 lic0002  1   0add  54 
3  2015-06-12 17:36:15 lic0003  1   0add  53 
4  2015-06-12 17:36:21 lic0001  1   0add  54 
5  2015-06-12 17:36:21 lic0002  1   0add  59 
6  2015-06-12 17:36:21 lic0003  1   0add  62 
7  2015-06-12 17:36:21 lic0004  1   0add  55 
8  2015-06-12 17:36:15 lic0001  1   0bdd  53 
9  2015-06-12 17:36:15 lic0002  1   0bdd  52 
10 2015-06-12 17:36:15 lic0003  1   0bdd  52 
11 2015-06-12 17:36:15 lic0004  1   0bdd  50 
12 2015-06-12 17:36:33 lic0002  1   0bdd  54 
13 2015-06-12 17:36:33 lic0003  1   0bdd  54 
14 2015-06-12 17:36:33 lic0004  1   0bdd  55 
15 2015-06-12 17:36:33 lic0005  1   0bdd  60 

我需要使用上面的相同数据并获取如下数据。我应该使用什么sql查询来获取下面的输出,但我只想使用相应设备的三个最高值。我知道我需要使用支点,但我有制定正确的查询

id date  timestamp deviceid storeid deviceid1 deviceid2 deviceid3 value1 value2 value3 
1 2015-06-12 17:36:15  0add  1  lic001  lic002  lic003  52  54  53  
2 2015-06-12 17:36:21  0add  1  lic002  lic003  lic004  59  62  55 
3 2015-06-12 17:36:15  0bdd  1  lic001  lic002  lic003  53  52  52  
4 2015-06-12 17:36:33  0bdd  1  lic002  lic004  lic005  54  55  60 

对于最后一行查询既可以返回lic002或lic003作为两个值相同的困难。

回答

1

如果接受你,最简单的方法可能是使用group_concat()substring_index()

select min(id) as id, date, timestamp, storeid, 
     substring_index(group_concat(device order by value desc), ',', 3) as devices, 
     substring_index(group_concat(value order by value desc), ',', 3) as values 
from mytable t 
group by date, timestamp, storeid; 

这使三个值成一列。如果你愿意的话,你可以将它们分成不同的列。否则,您需要列举值并且变得复杂 - 使用单个查询,您需要子查询/非等同元素(对您的数据大小而言可能非常昂贵)或变量。

+0

“否则...” - 如果您使用[技术在我的博客](http://mysql.rjweb.org/doc.php/groupwise_max#top_n_in_each_group),这并不算太坏。 –

+0

@RickJames。 。 。您的博客中的特定代码不安全,因为您在'select'中有多个变量赋值,逻辑取决于表达式的评估顺序。 MySQL不保证表达式评估的顺序。但是,如果此版本不符合OP的需求,那么还有其他方法。 –

+0

@GordonLinoff为什么我们需要min(id)在这里?我也看到查询在某种程度上起作用,但它不会将其限制为3个值,并且分隔符也不能被改变,就像是|。 – fheo