基于复杂折扣的MySQL总和

时间:2016-10-14 07:23:01

标签: mysql

我正在努力解决以下问题。 我有3个表,sh_product,sh_discount_class和sh_shipping_lines,如下所示:

sh_product:

idp  | product  | qMin  | discount_class  | pallet_class_id_int
1      product 1  10      1                 2
2      product 2  5       1                 0

sh_discount_class

discount_id  | title  | description  | discount_value
1              5%       5% tax         0.05

sh_shipping_lines

id  | sh_id  |  idp  | quantity  | value
1     49        1      10          120
2     49        2      1           240 

基本上,我想根据以下标准对所有值求和:

  1. 只要quantity sh_shipping_lines大于qMin 来自sh_product的产品的pallet_class_id_int应用相应的 来自sh_discount_class

  2. 的折扣
  3. 只要产品来自idp,就意味着     特定产品的数量是与pallet_class_id_int对应的pallet_class_id_int数量的两倍。实际上,idp代表表

  4. 中其他产品的SELECT DISTINCT sh_shipping_lines.idp, sh_discount_class.discount_value, sh_discount_class.description, SUM(sh_shipping_lines.quantity) as total, sh_product.qMin, if(sh_product.qMin>0 AND sh_product.qMin<SUM(if(sh_product.pallet_class_id_int>0, 2*sh_shipping_lines.quantity, sh_shipping_lines.quantity)), SUM(sh_shipping_lines.quantity)*sh_shipping_lines.value - SUM(sh_shipping_lines.quantity)*sh_shipping_lines.value*sh_discount_class.discount_value, SUM(sh_shipping_lines.quantity)*sh_shipping_lines.value) as val FROM sh_shipping_lines LEFT JOIN sh_product ON sh_product.idp = sh_shipping_lines.idp LEFT JOIN sh_discount_class ON sh_discount_class.discount_id = sh_product.discount_class WHERE sh_id=49 GROUP BY sh_shipping_lines.idp

    所以,在我的情况下,总和应该是(1440 - 5%)= 1368
    我尝试使用以下选择,但它仍然没有计算总值,因为它应该

    idp  | discount_value  | description  | total  |  qMin  | val
    1      0.05              product 1      10        10      1140
    2      0.05              product 2      1         5        228   
    

    期望的结果应如下所示:

    Action  = (reader["Action"]) == DBNull.Value ?'\0' : Convert.ToChar(reader["Action"]),
    

1 个答案:

答案 0 :(得分:1)

为您的查询添加了一些修复程序(使用qMin并删除DISTINCT - 我认为您不需要它)。我想sh_product中的qMin列是触发折扣的给定产品的最小数量?所以IF应该是:

sh_product.qMin <= SUM

idp 2的产品数量为1(如sh_shipping_lines表中所示),因此sh_shipping_lines中的第二个产品不会触发折扣的原因。 因此,IF对于产品1是正确的,但产品2进入ELSE,这就是原因 最后的总和是1380。

SELECT sh_shipping_lines.idp, sh_discount_class.discount_value, sh_discount_class.description,
SUM(sh_shipping_lines.quantity) AS total, sh_product.qMin, SUM(sh_shipping_lines.quantity)*sh_shipping_lines.value*sh_discount_class.discount_value,
    IF(sh_product.qMin>0 AND sh_product.qMin <= SUM(IF(sh_product.pallet_class_id_int>0, 2*sh_shipping_lines.quantity, sh_shipping_lines.quantity)), 
            SUM(sh_shipping_lines.quantity)*sh_shipping_lines.value - SUM(sh_shipping_lines.quantity)*sh_shipping_lines.value*sh_discount_class.discount_value, 
            SUM(sh_shipping_lines.quantity)*sh_shipping_lines.value
    ) AS val

FROM sh_shipping_lines

LEFT JOIN sh_product ON sh_product.idp = sh_shipping_lines.idp
LEFT JOIN sh_discount_class ON sh_discount_class.discount_id = sh_product.discount_class

WHERE sh_id=49
GROUP BY sh_shipping_lines.idp

此查询的结果是:

idp discount_value  description total   qMin    val
1   0.05    5% tax  10  10  1140.0000
2   0.05    5% tax  1   5   240.00

这个更新版本应该可行。它非常难看,但它适用于给定的输入:

SELECT  sh_shipping_lines.idp, sh_discount_class.discount_value, sh_discount_class.description,
SUM(sh_shipping_lines.quantity) AS total, sh_product.qMin, relatedQuantity, 
    IF(sh_product.qMin > 0 AND 
            (
                sh_product.qMin <= sh_shipping_lines.quantity 
                OR 
                sh_product.qMin <= (IF(sh_product.pallet_class_id_int=0, relatedQuantity, sh_shipping_lines.quantity))
            ),
            SUM(sh_shipping_lines.quantity)*sh_shipping_lines.value - SUM(sh_shipping_lines.quantity)*sh_shipping_lines.value*sh_discount_class.discount_value, 
            SUM(sh_shipping_lines.quantity)*sh_shipping_lines.value
    ) AS val

FROM sh_shipping_lines

LEFT JOIN sh_product ON sh_product.idp = sh_shipping_lines.idp
LEFT JOIN sh_discount_class ON sh_discount_class.discount_id = sh_product.discount_class

LEFT JOIN (
    SELECT relatedResult.idp AS originalIdp, sh_shipping_lines.idp, sh_shipping_lines.quantity*2 AS relatedQuantity
    FROM
    (
        SELECT sh_shipping_lines.*, prod.idp AS relatedIdp
        FROM sh_product
        JOIN sh_shipping_lines ON sh_shipping_lines.idp=sh_product.idp
        LEFT JOIN
            (SELECT idp, pallet_class_id_int FROM sh_product) AS prod ON prod.pallet_class_id_int=sh_product.idp
        WHERE sh_shipping_lines.sh_id=49
    ) as relatedResult
    LEFT JOIN sh_shipping_lines ON sh_shipping_lines.idp=relatedResult.relatedIdp
) AS result ON result.originalIdp=sh_shipping_lines.idp

WHERE sh_id=49
GROUP BY sh_shipping_lines.idp;