Фильтрация результатов по многим отношениям - PullRequest
2 голосов
/ 19 сентября 2010

Я бы хотел отфильтровать результаты запроса, который возвращает результаты из двух таблиц, которые имеют отношение один ко многим друг к другу.Рассмотрим следующий сценарий: (SQL Server или MS Access)
Таблица: Студенты
--StudentID
--StudentName

Таблица: Оценки
--StudentID (внешний ключ)
--CourseID (внешний ключ. Для простоты игнорировать)
--StudentGrade (из 100)

Теперь мне бы хотелосьчтобы отфильтровать результаты и вернуть только данные об оценках учащихся, у которых все оценки> 50. Сейчас я предпринимаю следующие шаги:
1- Получите всех учащихся и оценки:

DataTable dtAll = GetData("SELECT * FROM Students INNER JOIN Grades ON Students.StudentID = Grades.StudentID)  

2- Получить всех учеников, у которых есть хотя бы один класс <50. (Неполные ученики) </p>

    DataTable dtFailed = GetData("SELECT Distinct(Students.StudentID), Grades.StudentGrade FROM Students INNER JOIN INNER JOIN Grades ON Students.StudentID = Grades.StudentID WHERE Grades.StudentGrade < 50")  

3- Удалитьвсе поля, относящиеся к ошибочным ученикам:

foreach (DataRow failedRow in dtFailed.Rows)
        {
            int counter = 0;
            while (counter < dtAll.Rows.Count)
            {
                if (counter >= dtAll.Rows.Count)
                    break;
                curRow = dtAll.Rows[counter];

                if (Convert.ToInt32(curRow["StudentID"]) == Convert.ToInt32(failedRow["StudentlID"]))
                    dtAll.Rows.Remove(curRow);
                else
                    counter += 1;
            }
        }  

Этот кусок кода просто перебирает все строки dtFailed и удаляет строки в dtAll, которые имеют запись в dtFailed.(Все оценки учеников будут удалены, если у ученика будет хотя бы один провальный курс.) Я полагаю, что это распространенный сценарий в производственной среде, и, надеюсь, есть более быстрый и чистый способ сделать это.Спасибо, если кто-нибудь поделится им со мной.
PS Если это можно сделать только с помощью хранимых процедур или каким-либо специфическим для SQL способом (не для доступа), поделитесь им, поскольку я могу использовать SQL Server вместо MS Access, если это необходимо.

Ответы [ 2 ]

1 голос
/ 19 сентября 2010

Возможно, использовать LINQ для запроса вашего dtAll вместо повторного обращения к базе данных?

//student IDs having min grade greater than 50
 var studentIDs = from f in table.AsEnumerable()
                         group f by new { StuID = f.Field<int>("StudentID"), 
                                       StuGrade = f.Field<int>("StudentGrade") } 
                         into g
                         where g.Min(x => x.Field<int>("StudentGrade") > 50)
                         select new
                         {
                             StudentID = g.Key.StuID,
                             StudentGrade = g.Key.StuGrade
                         };


foreach (var item in studentIDs)
{
    Console.WriteLine(item.StudentID + " : " + item.StudentGrade);
}
1 голос
/ 19 сентября 2010
SELECT s.StudentId  ,
       s.StudentName,
       g.StudentGrade
FROM   Students s
       JOIN Grades g
       ON     g.StudentID = s.StudentID
WHERE  g.StudentGrade     > 50
AND    NOT EXISTS
       (SELECT *
       FROM    Grades g2
       WHERE   g2.StudentGrade <= 50
       AND     g.StudentID   = g2.StudentID)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...