2012-12-10 111 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';