Reputation: 659
I'm working in a procedure that returns a huge select where I wan't define how it is order. I wan't choose one of three fields and if it will be ascending or descending, if none of the three options was define, it returns by default the first field in descending
this way
ORDER BY
CASE option1
WHEN 0 THEN
CASE option2
WHEN 0 THEN firstField DESC
WHEN 1 THEN firstField ASC
END
WHEN 1 THEN
CASE option2
WHEN 0 THEN secondField DESC
WHEN 1 THEN secondField ASC
END
WHEN 2 THEN
CASE option2
WHEN 0 THEN thirdField DESC
WHEN 1 THEN thirdField ASC
END
ELSE
firstField DESC
END
END;
Of course, this didn't work... mysql acuses errors in words 'DESC' and 'ASC', how can I make this works??
Upvotes: 0
Views: 136
Reputation: 13110
In order to do this, you have to move the DESC/ASC to outside the case as they come after the expression.
You should also separate the fields. In a CASE statement if the fields have different datatypes, they will be converted into one that fits all (usually VARCHAR) and this can mess up the ordering.
You could do something like:
ORDER BY CASE WHEN option1=0 AND option2=0 THEN firstField END DESC,
CASE WHEN option1=0 AND option2=1 THEN firstField END ASC,
CASE WHEN option1=1 AND option2=0 THEN secondField END DESC,
CASE WHEN option1=1 AND option2=1 THEN secondField END ASC,
CASE WHEN option1=2 AND option2=0 THEN thirdField END DESC,
CASE WHEN option1=2 AND option2=1 THEN thirdField END ASC,
firstField DESC
Each case will return NULL for all rows when not applicable and thus have the same value. In fact the first case is unnecessary as it will be caught by the default, but I have included it for clarity. This may result in a hugely expensive ordering process however!
I think I'd much rather dynamically build the SQL and I'd use an array of allowed ordering values to keep it secure.
Upvotes: 1