PHP выполняет несколько сортировок с одним и тем же ресурсом $result

#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 .

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