MySql复杂查询 - 多列和变量列上的SUM

时间:2011-03-11 19:26:19

标签: mysql sql

我有以下表结构(简化版)

+----------------+  +-----------------+  +------+
| 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,则选择案例1下列出的值为0的所有费用。其他四个案例也是如此。

仅供参考,我在这里做的事情是我执行的实际查询,用法语写的(对不起,但由于我们是一个法语开发人员团队,我们大多用法语写代码和查询) :

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'

这是一个怪物!正如Ted Hopp所说:D

1 个答案:

答案 0 :(得分:1)

您可以使用IFNULL(manual_override, 非覆盖值 )