2011-03-11 44 views
0

我有以下的表結構(簡化版本)MySQL的複雜查詢 - 在多個和可變列SUM

+----------------+ +-----------------+ +------+ 
| fee_definition | | user_fee  | | user | 
+----------------+ +-----------------+ +------+ 
| id    | | user_id   | | id | 
| label   | | fee_id   | | ... | 
| case1   | | case   | +------+ 
| case2   | | manual_override | 
| case3   | +-----------------+ 
| case4   | 
| case5   | 
+----------------+ 

基座上的非常簡單的算法ID確定這種情況下,配合使用者確定的貨幣量他們必須支付。 user_fee可以基於1到沒有限制數量的費用定義。這意味着我可以有在交叉表

+-----------+----------+--------+-------------------+ 
| user_id | fee_id | case | manual_override | 
+-----------+----------+--------+-------------------+ 
| 1  | 1  | case1 |     | 
| 1  | 3  | case1 |     | 
| 1  | 5  | case1 | 50.22   | 
| 2  | 1  | case5 |     | 
| 3  | 1  | case2 |     | 
| 3  | 2  | case2 | 18.50   | 
+-----------+----------+--------+-------------------+ 

如果用戶被設置好的具有殼體1以下內容,其中的值是從0得到不同的情況下1中列出的所有費用拾取。其他四種情況也是如此。

僅供參考我如何在這裏做的事情是我執行的用法語寫的實際查詢(對不起,但由於我們是一個講法語的開發人員團隊,我們主要在我們的代碼和法語查詢中寫法語):

SELECT 
    `etudiant_etu`.*, 
    `session_etudiant_set`.*, 
    SUM(ROUND(frais_session_etudiant.fse_frais_manuel*100)/100) AS `fse_frais_manuel`, 
    `frais_session_etudiant`.`des_colonne`,   
    SUM(ROUND(definition_frais_des.des_quebecCanada*100)/100) AS `des_quebecCanada`,   
    SUM(ROUND(definition_frais_des.des_etranger*100)/100) AS `des_etranger`, 
    SUM(ROUND(definition_frais_des.des_non_credite*100)/100) AS `des_non_credite`, 
    SUM(ROUND(definition_frais_des.des_visiteur*100)/100) AS `des_visiteur`, 
    SUM(ROUND(definition_frais_des.des_explore*100)/100) AS `des_explore`, 
    `type_etudiant_tye`.*, 
    `type_formation_tyf`.*, 
    `pays_pys`.*, 
    `province_prc`.* 
FROM `etudiant_etu` 
INNER JOIN `session_etudiant_set` 
    ON session_etudiant_set.etu_id = etudiant_etu.etu_id 
INNER JOIN `frais_session_etudiant` 
    ON frais_session_etudiant.set_id = session_etudiant_set.set_id 
INNER JOIN `definition_frais_des` 
    ON definition_frais_des.des_id = frais_session_etudiant.des_id 
LEFT JOIN `type_etudiant_tye` 
    ON type_etudiant_tye.tye_id = session_etudiant_set.tye_id 
LEFT JOIN `type_formation_tyf` 
    ON type_formation_tyf.tyf_id = session_etudiant_set.tyf_id 
LEFT JOIN `pays_pys` 
    ON pays_pys.pys_code = etudiant_etu.pys_adresse_permanente_code 
LEFT JOIN `province_prc` 
    ON province_prc.prc_code = etudiant_etu.prc_adresse_permanente_code 
WHERE (set_session = 'P11') 
GROUP BY `session_etudiant_set`.`set_id` 
ORDER BY `etu_nom` asc, `etu_prenom` ASC 

作爲與簡化版本,從實際查詢參考:

simplified version   actual version 
fee_definition.id   definition_frais_des.des_id 
fee_definition.case1  definition_frais_des.des_quebecCanada 
fee_definition.case2  definition_frais_des.des_etranger 
fee_definition.case3  definition_frais_des.des_non_credite 
fee_definition.case4  definition_frais_des.des_visiteur 
fee_definition.case5  definition_frais_des.des_explore 

user_fee.user_id   frais_session_etudiant.set_id 
user_fee.fee_id   frais_session_etudiant.des_id 
user_fee.case    frais_session_etudiant.des_colonne 
user_fee.manual_override frais_session_etudiant.fes_frais_manuel 

user.id     session_etudiant_set.set_id 

我的問題是,當涉及到處理的手動操作設置。這樣做的最好方法是什麼?

我寧願在查詢中處理它,而不是在程序中處理。

的背後是什麼我找去如下

去收取一個用戶時,如果一個替代值被設定的費用總和,使用該值,而不是在設置好的實際值的邏輯fee_definition,否則使用fee_definition中的值。

我不介意鬆4不使用的情況下,只保留右列

編輯來顯示最終結果

這是我結束了查詢,IF的

的五個層次
'IF(`frais_session_etudiant`.des_colonne= "des_quebec_canada", 
    SUM(IF(`frais_session_etudiant`.fse_frais_manuel > 0, 
     ROUND(`frais_session_etudiant`.fse_frais_manuel*100)/100, 
     ROUND(definition_frais_des.des_quebec_canada*100)/100) 
    ), 
    IF(`frais_session_etudiant`.des_colonne= "des_etranger", 
     SUM(IF(`frais_session_etudiant`.fse_frais_manuel > 0, 
      ROUND(`frais_session_etudiant`.fse_frais_manuel*100)/100, 
      ROUND(definition_frais_des.des_etranger*100)/100) 
     ), 
     IF(`frais_session_etudiant`.des_colonne= "des_non_credite", 
      SUM(IF(`frais_session_etudiant`.fse_frais_manuel > 0, 
       ROUND(`frais_session_etudiant`.fse_frais_manuel*100)/100, 
       ROUND(definition_frais_des.des_non_credite*100)/100) 
      ), 
      IF(`frais_session_etudiant`.des_colonne= "des_visiteur", 
       SUM(IF(`frais_session_etudiant`.fse_frais_manuel > 0, 
        ROUND(`frais_session_etudiant`.fse_frais_manuel*100)/100, 
        ROUND(definition_frais_des.des_visiteur*100)/100) 
       ), 
       IF(`frais_session_etudiant`.des_colonne= "des_explore", 
        SUM(IF(`frais_session_etudiant`.fse_frais_manuel > 0, 
        ROUND(`frais_session_etudiant`.fse_frais_manuel*100)/100, 
        ROUND(definition_frais_des.des_explore*100)/100) 
       ), 
        0 
       ) 
      ) 
     ) 
    ) 
) as frais' 

這是一個怪物!泰德·霍普爲說:d

回答

1

您可以使用IFNULL(manual_override,非重寫的價值)

+0

謝謝你的提示。最後我沒有使用IFNULL,而是使用IF。如果要獲得正確的數據,我必須做5個級別,但最終數據更容易解析,因爲費用集中在一個領域。 – 2011-03-11 20:53:07

+0

@Jeff - 五層深?這是一個怪物!一定要記錄它的功能,因爲如果你像我一樣,一個月後sql將無法解讀。 :) – 2011-03-11 21:00:45

+0

編輯該問題以包含解決方案 – 2011-03-11 21:18:05