#php #mysql
#php #mysql
Вопрос:
Я не уверен, как это будет работать, но у меня 6000 студенческих оценок, которые принадлежат примерно 900 студентам. Я могу выполнить несколько функций выбора для этих данных, чтобы получить разумный ответ, но я должен поместить эту информацию в электронную таблицу, чтобы удалить студентов, которые не соответствуют критериям. Есть ли лучший способ?
Если я сделаю свой первый выбор, чтобы получить каждое уникальное имя учащегося, смогу ли я затем отсортировать результаты для средних значений более 80. Это не проблема, но я хотел бы удалить те, которые не соответствуют этим критериям, а затем выполнить другой выбор для тех студентов, у которых менее 8 курсов, и удалить их. Затем перейдите к окончательному списку и удалите любого студента, у которого нет 80 баллов по английскому языку.
Я могу выполнить каждый из них как отдельный оператор select, но я хочу сохранить каждый результат и использовать его на следующем шаге. В итоге я хотел бы получить список студентов, у которых среднее значение 80, 8 курсов, минимум 80 на английском языке…
Я знаю, что это возможно (если нет, это было бы безумием), но какой был бы лучший и наиболее эффективный способ сделать это, июньские отметки будут равны 24000 меткам, поэтому я предполагаю, что использование 6 запросов выбора не лучший метод? Для этого я использую PHP и MYSQL.
Я надеюсь, что этой информации достаточно, и я действительно ценю любое понимание этого.
Спасибо
PS вот структура таблицы:
table: students_marks
id stud_id gr student_# year course term mark per
415 31703 9 3100992316 2500 PHYE9 F1 78 78
416 31703 9 3100992316 2500 FR9 F1 50 50
417 31703 9 3100992316 2500 ENG9 F1 55 55
student_unique
id student_# First Last gr
50 3100992316 Amanda B 9
Я разделил его на две таблицы, чтобы упростить первую сортировку для уникальных учащихся, но после прочтения приведенного ниже ответа я вижу, что, вероятно, было бы лучше поместить все данные в одну таблицу. О, и если вам интересно, почему mark и percent, IB имеет отметки из 7, поэтому их необходимо преобразовать во что-то обычное при выполнении вычислений.
Комментарии:
1. Похоже, это можно сделать одним запросом. Не могли бы вы предоставить структуру (ы) ваших таблиц, чтобы нам было с чем работать?
Ответ №1:
Если все ваши данные находятся в одной таблице, вы можете выполнить все эти фильтры в одном операторе Select. Что-то вроде
SELECT AVG(Grades) As Average, StudentID,StudentName, Count(StudentCourses) As "Courses" FROM Students Where Average >= 80 AND Courses >= 8;
В противном случае вам нужно будет выполнить соединение или два. Мне нужно было бы просмотреть вашу таблицу, чтобы дать лучший ответ.
Комментарии:
1. Данные находятся в двух таблицах, но я могу довольно легко объединить их. Не понимал, что вы можете выполнить среднее значение (оценки) и количество (studentcourses) в одном и том же операторе select, который, вероятно, получит то, что мне нужно. Спасибо за помощь, это имеет смысл.
Ответ №2:
Я бы обратился к ArrayCollection Doctrine для выполнения такого рода задач. Но вы также можете сделать это с помощью старого доброго array_filter .
Допустим, вы сохраняете нефильтрованный результат в массиве $all_students
$all_students = $connection
->query("select * from students")
->fetchAll(PDO::FETCH_ASSOC);
Использование array_filter
$over_80_avg = array_filter($all_students, function($student, $index) {
return $student['avg'] >= 80;
}, ARRAY_FILTER_USE_BOTH));
$less_8_courses = array_filter($over_80_avg, function($student, $index) {
return $student['courses_count'] <= 8;
}, ARRAY_FILTER_USE_BOTH));
С помощью Doctrine ArrayCollection
Может быть излишним входить в doctrine (что, вероятно, означает попадание в composer, если вы этого не сделали) просто для выполнения этого, но в конечном итоге это окупится.
Создайте экземпляр ArrayCollection из исходного массива:
$all_students_collection= new DoctrineCommonCollectionsArrayCollection($all_students);
(пожалуйста, обратите внимание, что я использую полное пространство имен, поскольку я больше ничего не знаю о вашем коде)
ArrayCollections позволяют выполнять фильтры следующим образом:
$over_80_avg_collection = $all_students_collection->filter(function($student) {
return $student->avg >= 80;
});
Тогда каждая новая переменная, которую вы объявляете, может быть подфильтром первой или основной:
$less_8_courses_collection = $over_80_avg_collection->filter(function($student) {
return $student->courses_count <= 8;
});
Наконец, вам нужно будет преобразовать эти коллекции обратно в массивы, чтобы соответствовать вашему первоначальному намерению:
$over_80_avg = $over_80_avg_collection->toArray();
$less_8_courses = $less_8_courses_collection->toArray();
Другим способом было бы перейти прямо в библиотеку, которая предназначена только для добавления синтаксиса sugar в массивы, например Underscore.php .
В любом случае, вам нужно обрабатывать ваш исходный массив как неизменяемый, поэтому любыми способами избегайте любого метода, который передает массив в качестве ссылки, поскольку он также удалит строки из исходного массива.