2 Stimmen

Verkürzung einer sich wiederholenden 1400-zeiligen MySQL UNION-Abfrage mit PHP

Ich habe eine MYSQL-Tabelle, die 1275 Felder breit ist. Jede Zeile in der Tabelle stellt eine einzelne Klasse von Schülern dar, mit 17 Feldern pro Schüler, X bis zu 75 Schülern pro Klasse, also 17 X 75 = 1275 Felder.

Ich habe eine SQL UNION-Abfrage entwickelt, die die Schüler erfolgreich in eine andere Tabelle zieht, wobei jeder Schüler in einer einzelnen Zeile steht.

Nun möchte ich diese UNION-Abfrage als Teil eines PHP-Programms verwenden. Ich habe die Abfrage so, wie sie ist, in PHP "importiert". Aber gibt es nicht eine Möglichkeit, die SQL-Abfrage mit PHP zu verkürzen? Schamlos, hier ist mein Code:

    $sql = "
    INSERT INTO $t_mem2
    SELECT localcourse
         , statecourse
         , coursetitle
         , semester
         , section
         , teachercode
         , teachername
         , meetingcode
         , classpop
         , student_id_01 AS student_id
         ,        sex_01 AS sex
         ,        dob_01 AS dob
         ,      grade_01 AS grade
         ,     ethnic_01 AS ethnic
         ,  last_name_01 AS last_name
         , first_name_01 AS first_name
         , $c_sch        AS sch_code
    FROM $t_mem1
    UNION
    SELECT localcourse
         , statecourse
         , coursetitle
         , semester
         , section
         , teachercode
         , teachername
         , meetingcode
         , classpop
         , student_id_02 AS student_id
         ,        sex_02 AS sex
         ,        dob_02 AS dob
         ,      grade_02 AS grade
         ,     ethnic_02 AS ethnic
         ,  last_name_02 AS last_name
         , first_name_02 AS first_name
         , $c_sch        AS sch_code
    FROM $t_mem1
    UNION 
    SELECT localcourse
         , statecourse
         , coursetitle
<...snip..............................>
     , teachername
     , meetingcode
     , classpop
     , student_id_75 AS student_id
     ,        sex_75 AS sex
     ,        dob_75 AS dob
     ,      grade_75 AS grade
     ,     ethnic_75 AS ethnic
     ,  last_name_75 AS last_name
     , first_name_75 AS first_name
     , $c_sch        AS sch_code
  FROM $t_mem1
 ORDER
    BY localcourse
     , statecourse
     , semester
     , section
     , teachername
     , meetingcode
     , last_name
     , first_name" ;

3voto

Borealid Punkte 90999

Zunächst einmal zeigt diese Abfrage, dass Ihr Datenbankschema sehr, sehr schlecht ist.

Abgesehen davon können Sie die Abfrage mit PHP verkürzen:

$query = "INSERT INTO $t_mem2 ";
for ($i = 1; $i <= 75; $i++) {
    if ($i > 1) {
        $query .= ' UNION ';
    }
    $s = "$i";
    if ($i < 10) {
       $s = '0'.$s;
    }
    $query .= "SELECT localcourse
         , statecourse
         , coursetitle
         , semester
         , section
         , teachercode
         , teachername
         , meetingcode
         , classpop
         , student_id_{$s} AS student_id
         ,        sex_{$s} AS sex
         ,        dob_{$s} AS dob
         ,      grade_{$s} AS grade
         ,     ethnic_{$s} AS ethnic
         ,  last_name_{$s} AS last_name
         , first_name_{$s} AS first_name
         , $c_sch        AS sch_code FROM $t_mem1";
}
$query .= " ORDER
BY localcourse
 , statecourse
 , semester
 , section
 , teachername
 , meetingcode
 , last_name
 , first_name" ;

Dadurch wird die Abfrage "verkürzt", indem sie in PHP-Code generiert wird. Wenn Sie hingegen die Abfrage so gestalten wollen, dass sie wenn sie auf die Datenbank trifft kürzer ist, ist auch das möglich; ändern Sie einfach die obige Schleife, um mit $query bei jeder Iteration neu und fassen alle Ergebnisse in einem Array zusammen. Am Ende haben Sie 75 Abfragen gemacht, und PHP führt die UNION durch.

2voto

Wolph Punkte 73880

Lassen Sie mich der Erste sein, der sagt: OMG!

Zweitens: Lesen Sie etwas über Normalisierung: http://en.wikipedia.org/wiki/Database_normalization

Drittens: Verwenden Sie eine Schleife und ersetzen Sie 01 .. 75 con printf('%02d', $i)

2voto

Amadan Punkte 177506

Ich nenne WoLpHs OMG und rufe ein WTF.

Um ein bisschen mehr zu erklären, was die anderen mit "Normalisierung" meinen, möchten Sie hier (mindestens) zwei Tabellen haben: eine für Kurse, eine für Studenten (wahrscheinlich auch eine für Lehrer). Alle Felder mit einer Nummer gehen in die students Tisch, teachername y teachercode (möglicherweise mit einer id ) gehen in teachers Tabelle, und alles andere kommt in die courses Tabelle, zusammen mit einigen neuen Feldern: teacher_id (oder teachercode ) und student_id und vorzugsweise eine eigene AUTOINCREMENT ed id auch. Wenn Sie dann ähnliche Ergebnisse wie bei Ihrer 70 KB-Abfrage erhalten möchten, gehen Sie wie folgt vor:

SELECT C.id AS course_id
     , C.localcourse
     , C.statecourse
     , C.coursetitle
     , C.semester
     , C.section
     , T.teachercode
     , T.teachername
     , C.meetingcode
     , C.classpop
     , C.student_id
     , S.sex
     , S.dob
     , S.grade
     , S.ethnic
     , S.last_name
     , S.first_name
FROM courses C
JOIN students S ON C.student_id = S.id
JOIN teachers T ON C.teacher_id = T.id

Außerdem brauchen Sie wahrscheinlich keine classpop können Sie es bekommen mit SELECT COUNT(C.student_id) AS classpop ... GROUP BY C.id .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X