使用PHP缩短重复的1400行MySQL UNION查询

时间:2010-08-05 01:24:03

标签: php sql mysql union

我有一个1275字段宽的MYSQL表。表格中的每一行代表一个学生类别,每个学生有17个字段,每个类别X最多75个学生,因此17 X 75 = 1275个字段。

我设计了一个SQL UNION查询,成功将学生拉到另一个表中,每个学生都在一行中。

现在,我想将此UNION查询用作PHP程序的一部分。我已经将查询“导入”到PHP中了。但是,有没有办法使用PHP来缩短SQL查询?无耻地,这是我的代码:

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

3 个答案:

答案 0 :(得分:3)

首先,此查询表明您的数据库架构非常非常差。

除此之外,是的,您可以使用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" ;

这将通过在PHP代码中生成它来“缩短查询”。另一方面,如果你想要查询,因为它点击数据库更短,那也是可能的;只需修改上面的循环,在每次迭代中重新启动$query,并将所有结果放在一个数组中。你最终将得到75个查询,PHP将执行UNION。

答案 1 :(得分:2)

让我成为第一个说OMG的人!

其次,开始阅读规范化:http://en.wikipedia.org/wiki/Database_normalization

第三:使用循环并将01 .. 75替换为printf('%02d', $i)

答案 2 :(得分:2)

我打电话给WoLpH的OMG,我举起了WTF。

为了通过“规范化”更多地解释其他人的意思,你想在这里(至少)有两个表:一个用于课程,一个用于学生(可能还有一个用于教师)。带有数字的所有字段都会进入students表,teachernameteachercode(可能带有id)进入teachers表,其他一切都进入进入courses表格以及一些新字段:teacher_id(或teachercode)和student_id,最好是自己的AUTOINCREMENT ed id同样。然后,当您想要获得与70Kb查询类似的结果时,请执行以下操作:

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

另外,您可能不需要classpop,可以使用SELECT COUNT(C.student_id) AS classpop ... GROUP BY C.id获取。