2017-02-10 14 views
0

У меня есть основания полагать, что этот код можно сделать намного лучше, и, возможно, с гораздо большей частью работы с запросом для начала?SQL: Улучшить выбор запроса

Постараюсь объяснить это.

Каждая строка в моей базе данных имеет значение 1, 2 или 3 для exercise, а затем также номер rep, который может быть любым числом, но в этом коде я предпочитаю заботиться только о 1-12, так что это код выбирает строку с наивысшим значением kilograms (которая является столбцом и имеет значение для каждой строки), где exercise равно 1, а rep равно 1, а затем 2 и 3 и т. д. и т. д. и т. д. и т. д. и т. д. и т. д. и т. д. до 12, затем изменяется exercise на 2 и снова идет от 1-12, выбирая верхнюю строку kilograms.

Имеет ли это смысл?

for (var i = 1; i <= 3; i++) { 
    for (var ii = 1; ii <= 12; ii++) { 
     var getPR = "SELECT top 1 kg, rep, date FROM Test WHERE exerVariName = 'Comp' AND exercise = @0 AND rep = @1 order by kg desc"; 
     db.Execute(getPR, i, ii); 
     foreach (var get in db.Query(getPR, i, ii)) { 
      DateTime Date = get.Date; 
      var finalDate = Date.ToString("MMM d, yyyy"); 
      var weight = get.kg + "kg"; 
      var reps = "x " + get.rep; 
      <a>@weight @reps - @finalDate</a> 
      <br> 
     } 
    } 
} 

Я использую SQL Server Compact, и это не проект MVC.

+0

Пожалуйста, не говорите, что это часть cshtml файла? – trailmax

+0

Почему бы и нет? @trailmax –

+0

Файлы Razor созданы для применения данных модели представления в HTML-разметке. Запросы БД должны жить в контроллере и передавать модель представления с данными. (Предполагая MVC) – trailmax

ответ

3

Вы можете выбрать все интересующие вас строки только с одним запросом, используя Group By и MAX агрегированную функцию.

SELECT t.kg, t.rep, t.date 
FROM Test t 
INNER JOIN 
    (SELECT MAX(kg) as kg, exercise, rep 
    FROM Test 
    WHERE exerVariName = 'Comp' 
    GROUP BY exercise, rep) i 
ON t.exercise = i.exercise AND t.rep = i.rep AND t.kg = i.kg 
WHERE t.exerVariName = 'Comp' 

Внутренний запрос выполняется только один раз. Он находит идентификатор группы (exercise, rep) кортеж и соответствующее значение группы kg. Затем внутренний запрос соединяется с таблицей Test, чтобы получить «содержимое» строк (в вашем случае только одно дополнительное поле date).

Общая эффективность прекращается.

Вам нужно только перебрать результаты этого запроса.

См. this topic.


Edit:

Исключение нескольких (rep, exercise) записей, имеющих такой же kg (почти такой же результат, как зацикливание ФП) в

SELECT kg, rep, exercise, MAX(date) 
FROM 
    (SELECT t.kg, t.rep, t.exercise, t.date 
    FROM Test t 
    INNER JOIN 
     (SELECT MAX(kg) as kg, exercise, rep 
     FROM Test 
     WHERE exerVariName = 'Comp' 
     GROUP BY exercise, rep) i 
    ON t.exercise = i.exercise AND t.rep = i.rep AND t.kg = i.kg 
    WHERE t.exerVariName = 'Comp') t 
GROUP BY t.kg, t.rep, t.exercise 
+0

Я тестирую их прямо сейчас, я вижу, что мне нужно узнать больше о соединениях, потому что я не понимаю код haha, эти два разных запроса приводят к разным вещам, более поздний показывает половину количества строк, но я не уверен, какой из них правильный, но я бы тоже хотел «зацикнуться», чтобы я мог видеть что определить, правильно ли это или нет, если вы хотите помочь с этим! –

+0

Okey, поэтому мне удалось отобразить номер упражнения и сравнить его с результатами моего старого кода запроса/цикла, а когда «упражнение» равно 2 или 3, он получил все правильные результаты, однако, когда он был 1, он показал только 4 из 6 результатов, которые показал мой запрос, не могут понять, почему:/ –

+0

В чем «мой запрос» * вы говорите? Как я вижу, запрос 'getPR' может вернуть не более 1 результата. Вы говорите, что ваш запрос возвращен 6. –

0
SELECT kg, rep, date, exercise, rep FROM Test test1 WHERE rep = (SELECT TOP 1 test2.rep FROM Test test2 WHERE test2.exercise = test1.exercise AND test2.rep = test1.rep ORDER BY kg DESC) GROUP BY exercise, rep 

Прокрутите эти результаты и покажите их.

+0

привели к этой ошибке. Произошла ошибка при анализе запроса. [Номер строки токена = 1, смещение линии токена = 66, токен в ошибке = SELECT] ' –