2012-12-10 112 views
5

请看看这个SQL捣鼓表和何种查询我曾尝试空值:
SQL Fiddle如何返回使用SQL左连接

所以基本上,我有两个表,即tbl_curriculumtbl_enrolled_subjects

tbl_curriculum包含学生根据他的课程(course_id)应该采取的所有科目(subject_id)。
tbl_enrolled_subjects包含学生根据tbl_curriculum接受/注册的所有科目。

我要检查学生已采取哪些科目和这不,查询应该返回是这样的:

Subject_id|Grade|Status 
23  | 2 |Passed 
24  | 2 |Passed 
31  | 2 |Passed 
50  | 2 |Passed 
83  | 1 |Passed 
27  |NULL |NULL 
28  |NULL |NULL 
29  |NULL |NULL 

。 。 。 等等。

具有成绩和状态的Subject_ID表示学生已经学习了该科目。另一方面,NULL值表示学生尚未接受这些科目。
我用这个查询:

SELECT a.subject_id, b.grade, b.status 
FROM tbl_curriculum a 
LEFT JOIN tbl_enrolled_subjects b 
ON a.course_id = b.course_id AND a.subject_id = b.subject_id 
WHERE b.student_id_no='05-0531'; 

,但我一直只获得学生已经修读的科目。

Subject_id|Grade|Status 
23  | 2 |Passed 
24  | 2 |Passed 
31  | 2 |Passed 
50  | 2 |Passed 
83  | 1 |Passed 

我错过了什么吗?提前致谢。

+0

你不能,where子句需要评估为真 – ajreal

+0

@ajreal我应该怎么做呢? –

回答

5

您目前还没有找到任何空的原因是因为你的WHERE子句是搜索与填写了student_id_no行。但是,对于你的数据,student_id_no在学生没有上课的情况下也是空的......因此你正在过滤掉这些数据。

试试这个:

SELECT a.subject_id, b.grade, b.status, b.student_id_no 
FROM tbl_curriculum a 
LEFT JOIN tbl_enrolled_subjects b 
ON a.course_id = b.course_id AND a.subject_id = b.subject_id 
where student_id_no is null or student_id_no = '05-0531' 
order by subject_id 

http://sqlfiddle.com/#!2/4c7b2/43

+0

这有效,但当试图对我的数据库包含100k +记录,它花了103秒,你能告诉我什么领域,我应该添加索引? –

+0

由于左连接意味着返回左表中的所有结果,因此我会首先确定是否仅从tbl_curriculum中选择所有结果都会导致缓慢。如果不是,那么我们使用的唯一其他实际字段是student_id_no和我们正在使用course_id和subject_id加入的两个字段。我会在那里尝试。一般来说,查看查询执行计划也是一个好主意。 http://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html – purgatory101

1

尝试此查询::

SELECT a.subject_id, b.grade, b.status 
FROM tbl_curriculum a 
JOIN tbl_enrolled_subjects b 
ON a.course_id = b.course_id AND a.subject_id = b.subject_id 
WHERE b.student_id_no='05-0531' 
union 
select subject_id,null,null 
from tbl_curriculum 
where concat(subject_id,course_id) not in (
    select concat(subject_id,course_id) 
from tbl_enrolled_subjects 
WHERE student_id_no='05-0531') 
+0

这也适用,但是当我在包含100k +记录的数据库上尝试时,它非常缓慢。你有什么想法应该在什么领域添加索引?谢谢。 –

2

其实很简单,你用IS EMPTY

在你的实体已经定义了一个反键,然后你打电话给你的实体主体,其中逆关键是空。

SELECT a FROM tbl_curriculum a WHERE a.enrollers IS EMPTY; 

然后我定义了一个领域的课程像tbl_enrolled_subjectstbl_curriculum

/** 
* 
* @ORM\OneToMany(targetEntity="tbl_enrolled_subjects", mappedBy="id") 
*/ 
private $enrollers; 
0

我相信,把学生过滤器进入连接谓词也给出了理想的效果。它在SQL小提琴中工作,但我不知道它是如何影响查询计划的。

SELECT a.subject_id, b.grade, b.status 
FROM tbl_curriculum a 
LEFT JOIN tbl_enrolled_subjects b 
ON a.course_id = b.course_id AND a.subject_id = b.subject_id 
**AND** b.student_id_no='05-0531';