Reputation: 1038
I'm currenty working on the project that has an sql expressions to do some calculations in the database as follows:
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
This works well enough, but it seems bad to me to have the outer case expressions THEN
clauses to be pretty much exactly the same apart from the * -1
. Is there a way to express this so that the first case expression just gets multiplied by the second something along the lines of:
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
Seems like something that would be possible to do, but I'm not sure how.
Upvotes: 1
Views: 776
Reputation: 1269873
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.
Upvotes: 2