2013-03-13 65 views
1

背景如何做一個MYSQL條件選擇語句

我面臨着以下的問題,涉及三個表

class_sectors表包含三種類型的類

classes表中包含一個學生可參加的班級列表

class_choices包含第一,第二和第三班的選擇學生,每個部門。因此,對於部門1 Student_A已class_1作爲第一choihce,class_3作爲第二選擇和class_10,例如第三個選擇,然後扇區2他還有三種選擇,等等。

class_choices表中有這些列:

kp_choice_id | kf_personID | kf_sectorID | kf_classID | preference | assigned 

我認爲列名是不言自明的。 preference是1,2或3.並且assigned是一個布爾值,設置爲1,一旦我們檢查了學生的選擇並將它們分配給一個班級。

問題

寫一個SQL查詢,告訴他們被分配到每個部門有什麼類的學生。如果他們的班級沒有被分配,它應該默認顯示他們的第一選擇。

其實我已經得到了這個工作,但使用兩(很臃腫?)的SQL查詢如下:

$choices = $db -> Q("SELECT 
    *, concat_ws(':', `kf_personID`, `kf_sectorID`) AS `concatids` 
FROM 
    `class_choices` 
WHERE 
    (`assigned` = '1') 
GROUP BY 
    `concatids` 
ORDER BY 
    `kf_personIDID` ASC, 
    `kf_sectorID` ASC;"); 

$choices2 = $db -> Q("SELECT 
    *, concat_ws(':', `kf_personID`, `kf_sectorID`) AS `concatids` 
FROM 
    `class_choices` 
WHERE 
    `preference` = '1' 
GROUP BY 
    `concatids` 
HAVING 
    `concatids` NOT IN (".iimplode($choices).") 
ORDER BY 
    `kf_personID` ASC, 
    `kf_sectorID` ASC;"); 

if(is_array($choices2)){ 
    $choices = array_merge($choices,$choices2); 
} 

現在$choices確實有我想要的東西。

但我敢肯定,有一種方法可以簡化這一點,合併兩個SQL查詢,所以它更輕量一些。

是否有某種有條件的SQL查詢可以做到這一點???

回答

1

您的解決方案使用兩個步驟使您能夠根據需要過濾數據。由於您正在生成報告,因此即使看起來比您想要的更冗長一些,這也是一個非常好的方法。

這種方法的優點是調試和維護更容易,這是一大優勢。

要改善這種情況,您需要考慮數據結構本身。當我查看class_choices表時,我看到以下字段:kf_classID, preference, assigned其中包含關鍵信息。

對於每個班級,assigned字段可以是0(默認)或1(當爲學生分配班級首選項時)。默認情況下,preference = 1的班級是assigned=0,因爲您在報告中顯示該班級的所有學生在特定部門的班級選擇。
對於preference=1設置默認值assigned=1

的數據模型可以通過實施業務規則如下改進。當類選擇過程 發生時,如果學生被分配了第二或第三選擇,則首選項1未分配,並且分配了替代選項。

這意味着應用程序中有更多的代碼,但它使報告更容易一些。

難度的來源是分配過程沒有明確指定第一個首選項。如果學生無法獲得第一選擇,它只會更新assigned

總之,你的SQL很好,而且改進來自再看看數據模型。

希望這會有所幫助,祝你工作順利!

+0

啊,顯而易見!!!感謝您花時間思考。優秀的答案。 – Emmanuel 2013-03-13 20:45:47

+0

非常歡迎您,在灰色的細胞中鍛鍊身體! – 2013-03-13 20:46:37

+0

哈哈,是的,當然! – Emmanuel 2013-03-13 20:47:13