简化嵌套的CASE表达式

时间:2018-02-15 12:26:04

标签: mysql sql case

我目前正在处理具有sql表达式的项目,以便在数据库中进行一些计算,如下所示:

SELECT
  SUM( 
    CASE models.type
    WHEN 'type_1'
      THEN ( CASE models.attribute_id 
             WHEN other_models.other_attribute_id
               THEN ROUND(models.value * other_models.conversion, 2)
             ELSE
               models.value   
             END ) * -1
    WHEN 'type_2'
      THEN ( CASE models.attribute_id 
             WHEN other_models.other_attribute_id
               THEN ROUND(models.value * other_models.conversion, 2)
             ELSE
               models.value   
             END )
    END
  ) as value

这很好用,但除了THEN之外,让外部案例表达式* -1子句几乎完全相同对我来说似乎不好。有没有办法表达这一点,以便第一个案例表达式乘以第二个东西:

  SELECT
    SUM( 
      CASE models.attribute_id 
      WHEN other_models.other_attribute_id
        THEN ROUND(models.value * other_models.conversion, 2)
      ELSE
        models.value   
      END * (CASE models.type
             WHEN 'type_1'
               THEN -1
             WHEN 'type_2'
               THEN 1
             END)
    ) as value

似乎有可能做的事情,但我不确定如何。

1 个答案:

答案 0 :(得分:2)

You do not need to nest case expressions:

SELECT SUM(CASE WHEN models.type = 'type_1' AND models.attribute_id = other_models.other_attribute_id
                THEN - ROUND(models.value * 10)
                WHEN models.type = 'type_1'
                THEN - models.value   
                WHEN models.type = 'type_2' AND models.attribute_id = other_models.other_attribute_id
                THEN ROUND(models.value * 10)
                WHEN models.type = 'type_2'
                THEN models.value   
           END) as value

However, repeating all the logic seems unnecessary. If you only have the two types, I would go for:

SELECT (models.value *
        (CASE WHEN models.attribute_id = other_models.other_attribute_id THEN 10 ELSE 1 END) *
        (CASE WHEN models.type = 'type_1' THEN -1 ELSE 1 END)
       ) as value

These are only slightly more complicated if you have other types that you want to ignore.

I should also note that I don't recommending rounding before the aggregation, unless that is really what you intend. If you want the result to be rounded, then round afterwards.