与mysql连接的多个foreach循环

时间:2018-08-31 15:22:51

标签: php mysql

我不确定我的数据库设计和编码结构是否有效或无法获取预期结果。

例如,我必须在每个主题每个学期中获取学生smith的详细信息,他的一般信息和获得的分数,并使用每个类别

以下是我的数据库结构

学生

id  |   Roll    |   name    |   class
=====================================
1   |   1       |   smith   |   7

主题

id  |   title
=============
1   |   Science
2   |   Math

考试

id  |   title
=================
1   |   First Term 
2   |   Second Term

标记

id  |   std_id  |   sub_id  |   th  |   pr  |   exm_id
======================================================
1   |   1       |   1       |   60  |   20  |   1
2   |   1       |   2       |   55  |   18  |   1
3   |   1       |   1       |   70  |   23  |   2
4   |   1       |   2       |   61  |   19  |   2

现在我正尝试获取结果

Name : Smith
class:  7
Progress Report
    First Term
        Science
            Th:60 | PR:20
        Math
            Th:55 | PR:18

    Second Term
        Science
            Th:70 | PR:23
        Math
            Th:61 | PR:19

但是,下面输出的是我得到的结果,我无法按考试方式获取结果,因此所有考试彼此共享所有分数

Name : Smith
class:  7
Progress Report
    First Term
        Science
            Th:60 | PR:20
        Math
            Th:55 | PR:18
        Science
            Th:70 | PR:23
        Math
            Th:61 | PR:19

    Second Term
        Science
            Th:60 | PR:20
        Math
            Th:55 | PR:18
        Science
            Th:70 | PR:23
        Math
            Th:61 | PR:19

我尝试过group.byexam.id,尽管它会按考试方式获取期望的结果,但它会重复同一学生

Name : Smith
class:  7
Progress Report
    First Term
        Science
            Th:60 | PR:20
        Math
            Th:55 | PR:18

Name : Smith
class:  7
Progress Report
    Second Term
        Science
            Th:70 | PR:23
        Math
            Th:61 | PR:19

这是 Mysql和PHP代码

$result=$con->prepare(
    "SELECT
        student.id, student.rid, student.name AS name, student.class,

        class.title AS class, 

        GROUP_CONCAT(DISTINCT exam.title) AS exam,
        GROUP_CONCAT(subject.title, '<br/> Th - ', mark.th, ' | PR - ', mark.pr SEPARATOR ',') AS mark

        FROM student
        JOIN class ON class.id = student.class 
        JOIN mark ON mark.std_id = student.id
        JOIN exam ON exam.id = mark.exm_id
        JOIN subject ON subject.id = mark.sub_id

        WHERE student.id=:id
        GROUP BY student.id;" //If exam.id is added here, it works but repeats student
) or die($con->error);

$result->bindParam(':id',$_POST['std']);
$result->execute();
while($row=$result->fetch(PDO::FETCH_ASSOC)){
    $name=$row['name'];
    $class=$row['class'];
    $exm_array = explode(',',$row['exam']);
    $mrk_array = explode(',',$row['mark']); 
    echo "
    Name: $name<br/>
    Class: $class<br/>
    Progress Report<br/>";

    // I think there are other fine alternative way instead of foreach

    foreach(array_values($exm_array) as $i => $exam){
        echo "<span class='col100'>".$exam."<br/>Mark:</span>";
        foreach(array_values($mrk_array) as $i => $mark){
            echo "<span class='col100'> ".$mark."</span>";
        }
    }
}

原始输出 enter image description here

1 个答案:

答案 0 :(得分:1)

这是我最好的实现方法。

  1. 将标记加载到PHP数组
  2. 通过修改后的查询(仅一个GROUP_CONCAT())吸引学生
  3. 显示学生姓名
  4. 从预加载的数据中为学生获取正确的术语
  5. 遍历数组以显示每个词条

第一个查询,加载所有标记:

SELECT
    student.id,
    exam.title AS exam,
    GROUP_CONCAT(subject.title, '<br/> Th - ', mark.th, ' | PR - ', mark.pr SEPARATOR ',') AS mark
FROM student
    JOIN mark ON mark.std_id = student.id
    JOIN exam ON exam.id = mark.exm_id
    JOIN subject ON subject.id = mark.sub_id
GROUP BY
    student.id,
    exam.title

并将其存储在PHP数组中,就像您拥有$marks_array

然后遍历学生:

SELECT
    student.id,
    student.rid,
    student.name AS 'name',
    student.class,
    class.title AS 'class_title'
FROM student
    JOIN class ON class.id = student.class

在循环内调用正确的记录再次循环:

$marks_array[<student_id>]-这将是一个具有两个值的数组(每次考试一个)

尝试一下,让我知道是否合理。