查询输出的行数多于应该执行的行数

时间:2011-10-30 12:56:09

标签: php mysql database

以下是我的询问:

$query = "
          SELECT gr.SessionId, t.TeacherUsername, s.ModuleId, m.ModuleName, 
      st.CourseId, st.Year, st.StudentUsername, gr.Mark, gr.Grade
      FROM Teacher t
          INNER JOIN Session s ON t.TeacherId = s.TeacherId
          JOIN Grade_Report gr ON s.SessionId = gr.SessionId
          JOIN Student st ON gr.StudentId = st.StudentId
          JOIN Course c ON st.CourseId = c.CourseId
          JOIN Course_Module cm ON c.CourseId = cm.CourseId
          JOIN Module m ON cm.ModuleId = m.ModuleId
          WHERE
            ('".mysql_real_escape_string($sessionid)."' = '' OR gr.SessionId = '".mysql_real_escape_string($sessionid)."')
          ";

以下是查询输出的内容:

Session ID  TeacherUsername Module Number   ModuleName  Course ID   Year    Student Username    Mark    Grade
AAA            m.prigmore   CHT2520        Web Program  INFO102      1      u1231231            69       B
AAA            m.prigmore   CHT2520        Database     INFO102      1      u1231231            69       B
AAA            m.prigmore   CHT2520        Web Program  INFO102      2      u0833421            71       A
AAA            m.prigmore   CHT2520        Database     INFO102      2      u0833421            71       A

如果你仔细看看发生了什么,我在Course_Module表中用来加入Course表和Module表,那么'INFO102'课程有2个模块。因此,它显示了4行,因为它试图为每个学生显示两个模块名称(来自模块表)。这是不正确的,因为它应该只链接到属于会话的模块,该模块应该是“Web程序”,而不是“数据库”(这是因为ModuleNumber CHT2520 =模块表中的'Web程序')。

以下是它应该输出的内容:

Session ID  TeacherUsername Module Number   ModuleName  Course ID   Year    Student Username    Mark    Grade
    AAA            m.prigmore   CHT2520        Web Program  INFO102      1      u1231231            69       B
    AAA            m.prigmore   CHT2520        Web Program  INFO102      2      u0833421            71       A

那么如何摆脱“ModuleName”下的“数据库”行并且模块号只与正确的模块名称匹配?

谢谢

2 个答案:

答案 0 :(得分:1)

问题是你从Session表中获取ModuleNumber,从Module表中获取ModuleName。您的查询说:“对于本次会议,获取所有成绩报告,并获得所有成绩报告,让所有学生,所有学生,获得所有课程,所有课程,获得所有课程模块链接,并为所有课程 - 模块链接,获取所有模块。“

这就是为什么您会看到为成绩报告,学生,课程和模块组合列出的所有模块的原因。你可以添加“AND s.ModuleId = m.ModuleId”,这应该修复它。我假设您在会话表中有ModuleId,如果您还有ModuleNumber。如果是这样,您在Session表中不需要ModuleNumber。

答案 1 :(得分:0)

您需要将ModuleID用作WHERE语句的一部分。我不熟悉MySQL,所以为了避免屠杀,我将使用伪SQL:

WHERE 
    ((gr.SessionID = '' OR gr.SessionID = $SessionID)
AND
    (cm.ModuleID = $ModuleID))

请注意,OR条件必须是更大AND规范的一个组件。

换句话说,您需要在标准中区分这两个模块。

当然,这假定名为“Web程序”的模块是唯一的,并且具有与名为“数据库”的模块不同的ModuleID。但是,他们各自在结果集中共享“模块编号”的事实让我感到担忧。如果模块表中没有唯一且不同的ID,则需要在“ModuleName”字段上加入,或者(更重要的是)确保模块在数据模型中唯一定义。

如果两个具有不同名称且表示不同条件选项的模块由表中的单个记录表示,则存在基本的设计问题。

无论如何,这是我尝试将MySQL查询放在一起的尝试。再说一遍,我可能会扼杀语法。似乎那里有很多额外的标点符号。 。 。 ; - )

$query = " 
      SELECT * 
      FROM Teacher t 
      INNER JOIN Session s ON t.TeacherId = s.TeacherId 
      JOIN Grade_Report gr ON s.SessionId = gr.SessionId 
      JOIN Student st ON gr.StudentId = st.StudentId 
      JOIN Course c ON st.CourseId = c.CourseId 
      JOIN Course_Module cm ON c.CourseId = cm.CourseId 
      JOIN Module m ON cm.ModuleId = m.ModuleId 
      WHERE 
        ('".mysql_real_escape_string($sessionid)."' = '' 
      OR gr.SessionId = '".mysql_real_escape_string($sessionid))."'
      AND cm.ModuleID = '".mysql_real_escape_string($moduleid)."') 
      "; 

希望有所帮助。