Получите максимум x строк плюс всю информацию о рядах для каждой группы в mysql to linq - PullRequest
1 голос
/ 22 сентября 2011

Некоторое время назад я нашел удобный запрос для 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;

, если я изменю <1, скажем, 2, 3 или x, я могу получить верхний x для id2, где id1 = 1 (так, два одинаковых id2 с разными id3)вот так: </p>

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 строками).Могу ли я получить тот же результат с использованием другого запроса (я не смог его получить).Б) Как я могу перевести это на 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 с его наибольшим значением.Вот почему в этом случае я получаю, например, строку с идентификатором 2. 11 является наибольшим из 10,11 и 9, где id1 = 1 и id2 = 1.и именно поэтому я получаю строку с идентификатором 8, потому что там, где id1 = 1 и id2 = 3, наибольшее значение для значения столбца равно 34. Если я изменю запрос на <2, я получу первые два.для id2 = 1 и id2 = 3 это даст строки с идентификаторами 8 и 11. Это лучше объяснить? </p>

Ответы [ 2 ]

1 голос
/ 28 сентября 2011

Воссоздал вашу таблицу в 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}

0 голосов
/ 26 сентября 2011

Как это:

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) };
...