2010-08-05 7 views
2

J'ai une table MYSQL qui est 1275 de vastes champs. Chaque rangée du tableau représente une seule classe d'élèves, avec 17 champs par élève, X jusqu'à 75 élèves par classe, donc 17 X 75 = 1275 champs.Raccourcir une ligne répétitive 1400 requêtes MySQL avec PHP UNION

J'ai mis au point une requête SQL UNION qui tire avec succès les étudiants dans une autre table, chaque étudiant sur une seule ligne.

Maintenant, je veux utiliser cette requête UNION dans le cadre d'un programme PHP. J'ai "importé" la requête en PHP telle qu'elle est. Mais, n'y at-il pas un moyen d'utiliser PHP pour raccourcir la requête SQL? Sans vergogne, voici mon 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" ; 
+6

Les choses raccourciraient si vous normalisez la base de données. –

+1

Vous compliquez votre vie en n'utilisant pas une base de données relationnelle de la manière prévue, à savoir maintenir les données de manière efficace en utilisant les relations entre les tables. Regardez dans la normalisation et sauvez-vous des heures de futurs maux de tête. – Tahbaza

+0

Mais la table de 1275 colonnes est donnée dans ce projet, pas une option. Je n'ai pas fait la table. C'est ce que tu veux dire? – dave

Répondre

3

Tout d'abord, cette requête indique que votre schéma de base de données est très, très pauvre.

Cela mis à part, oui, vous pouvez raccourcir la requête avec PHP:

$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" ; 

Cela « raccourcir la requête » en générant dans le code PHP. Si, d'autre part, vous cherchez à faire la requête comme il frappe la base de données plus courte, c'est aussi possible; Il suffit de modifier la boucle ci-dessus pour recommencer $query à chaque itération, et glom tous les résultats ensemble dans un tableau. Vous obtiendrez 75 requêtes et PHP exécutera l'UNION.

+0

Au lieu d'utiliser une instruction if pour '$ i <10', il pourrait être plus clair d'utiliser' sprintf' ou 'str_pad' à la place. De plus, ajouter tout à un tableau et utiliser 'implode' pourrait rendre le code encore plus facile à lire :) +1 btw – Wolph

+0

Merci, Borealid. C'était très rapide et je vais implémenter votre solution. Cette "large" table est un téléchargement d'une agence gouvernementale d'état. Si vous voulez les enfants dans une école, c'est ce que vous obtenez. Période. :-) – dave

+0

@WoLpH: Vous avez raison sur les deux points. Ma réflexion sur le premier était juste que c'est si simple que vous pourriez aussi bien faire le bloc '$ i <10' facilement lisible. Je pense que la raison pour laquelle je n'ai pas utilisé 'implode' était parce que j'avais déjà pris la requête de 1400 lignes à 20 :-P. – Borealid

2

j'appelle OMG Wolph, et je soulever une WTF. Pour expliquer un peu plus ce que les autres entendent par "normalisation", vous voulez avoir (au moins) deux tableaux ici: un pour les cours, un pour les étudiants (probablement aussi un pour les enseignants). Tous les champs avec un certain nombre vont dans la table students, teachername et teachercode (éventuellement avec un id) aller dans la table teachers, et tout autre va dans la table courses, ainsi que quelques nouveaux champs: teacher_id (ou teachercode) et student_id, et de préférence son propre AUTOINCREMENT ed id également. Ensuite, lorsque vous voulez obtenir des résultats similaires à votre requête 70Kb, vous faites ceci:

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 

, vous n'avez pas besoin probablement classpop, vous pouvez l'obtenir avec SELECT COUNT(C.student_id) AS classpop ... GROUP BY C.id.

+0

Merci. J'ai besoin de devenir plus familier avec la normalisation. Pas d'excuses, sauf que dans mon travail, je peux utiliser une table pour obtenir certaines données, résoudre un problème mineur, puis je ne pourrai plus jamais utiliser la table. Donc, il y a peu ou pas de permanence dans tout ce que je fais. – dave