获取max x行以及每个组的所有行信息,在mysql中为linq

时间:2011-09-22 11:18:05

标签: c# mysql linq greatest-n-per-group

不久之前,我发现了一个方便的mysql查询,以获得每组的前X个。 这就是我的意思:

如果这是表格:

rid id1 id2 id3 value
1   1   1   1   10
2   1   1   2   11
3   1   1   3   9
4   1   2   1   20
5   1   2   2   18
6   1   2   3   23
7   1   3   1   30
8   1   3   2   34
9   1   3   3   31
10  1   3   4   27
11  1   3   5   32
12  1   4   1   41
13  1   4   2   40
14  1   4   3   43
15  1   5   1   53
16  1   5   2   51
17  1   5   3   50
18  2   1   1   11
19  2   1   2   9
20  2   1   3   12

我想得到这个结果:

rid id1 id2 id3 value
2   1   1   2   11
6   1   2   3   23
8   1   3   2   34
14  1   4   3   43
15  1   5   1   53

我可以通过运行以下mysql查询来获得这个:

SELECT * FROM
  (SELECT * FROM idsandvalue 
   WHERE id1=1 AND 
     (SELECT COUNT(*) FROM idsandvalue AS helper 
      WHERE helper.id1 = idsandvalue.id1 
      AND helper.id2= idsandvalue.id2 
      AND helper.value > idsandvalue.value
     ) < 1
  )a;

如果我改变&lt; 1让我们说2,3或x我可以获得每个id2的顶部x,其中id1 = 1(所以,两个相同的id2具有不同的id3),如下所示:

rid id1 id2 id3 value
1   1   1   1   10
2   1   1   2   11
4   1   2   1   20
6   1   2   3   23
8   1   3   2   34
11  1   3   5   32
12  1   4   1   41
14  1   4   3   43
15  1   5   1   53
16  1   5   2   51
两个问题。 A)MySQL中的查询速度不是很快。需要一段时间(运行一个包含3207394行的表)。我可以使用不同的查询得到相同的结果(我无法得到它)。 B)我怎样才能将其翻译成linq?由于奇怪的where语句,我不知道如何将其转换为linq。

(后来我也添加了这个额外的问题) 在MySQL中我使用此查询:

SELECT *,COUNT(*) AS Counter FROM idsandvalue GROUP BY id1,id2;

得到这个结果:

rid id1 id2 id3 value   Counter
1   1   1   1   10       3
4   1   2   1   20       3
7   1   3   1   30       5
12  1   4   1   41       3
15  1   5   1   53       3
18  2   1   1   11       3

我也很难将其翻译成Linq。

(额外信息太大而无法发表评论)

嗨约翰(感谢您的快速回复)。 使用这个mysql查询

SELECT * FROM 
  (SELECT * FROM idsandvalue 
   WHERE id1=1 AND 
     (SELECT COUNT(*) FROM idsandvalue AS helper 
      WHERE helper.id1 = idsandvalue.id1 
      AND helper.id2= idsandvalue.id2 
      AND helper.value > idsandvalue.value
     ) < 1
  )a 

我尝试为每个分组的id1和id2获取最大值的行。这就是为什么在这种情况下我得到例如id为2的行.11是10,11和9中的最大值,其中id1 = 1且id2 = 1。这就是为什么我得到id为8的行,因为其中id1 = 1且id2 = 3,列值的最大值为34.如果我将查询更改为&lt; 2,我获得前两名。对于id2 = 1和id2 = 3,这将给出id为8和11的行。这有更好的解释吗?

2 个答案:

答案 0 :(得分:1)

在SQL Server中重新创建表并针对它运行查询,而不是通过linqer转换查询:

from a in ((from idsandvalue in db.idsandvalue whereidsandvalue.id1 == 1 &&

    (from helper in db.idsandvalue
    where
      helper.id1 == idsandvalue.id1 &&
      helper.id2 == idsandvalue.id2 &&
      helper.value > idsandvalue.value
    select new {
      helper
    }).Count() < 1
select new {
  idsandvalue
}))

选择新{   a.idsandvalue.rid,   a.idsandvalue.id1,   a.idsandvalue.id2,   a.idsandvalue.id3,   a.idsandvalue.value }

答案 1 :(得分:0)

这是怎么回事:

var takeRows = 2; // or whatever value you want
var q = from i in idsandvalue
        group i by new { i.ID1, i.ID2 } into g
        orderby g.Key.ID1, g.Key.ID2
        select new { g.Key.ID1, g.Key.ID2, TopValues = g.OrderByDescending(i => i.Value).Take(takeRows) };