I have a fairly complex case
statement that works in MySQL:
SELECT # rest of code omitted
CASE WHEN code = 'a' THEN 'x'
WHEN code IN ('m', 'n') THEN 'y'
WHEN class IN ('p', 'q') AND amount < 0 THEN 'z'
ELSE NULL END AS status
FROM # rest of code omitted
However, all attempts to write this in Sequel have failed. I am using this as a template:
Sequel.case([[:c, 1], [:d, 2]], 0) # (CASE WHEN "c" THEN 1 WHEN "d" THEN 2 ELSE 0 END)
(from Jeremy Evans' Github)
My best guess would be:
dataset.select( # rest of code omitted...
[[(:code => 'a'), 'x'],
[(:code => 'b'), 'y'],
[(:class => ['p', 'q'], :amount < 0), 'z']].case(nil).as(:status))
Any ideas?
SQL Case Statement Syntax Then for a single condition you can write the keyword WHEN followed by the condition that has to be satisfied. After that comes the keyword THEN and the value for that condition, like WHEN <condition> THEN <stuff> . This can then be followed by other WHEN / THEN statements.
In the Nested CASE expression, the outer statement executes until satisfying a condition. Once the condition is met, the inner CASE expression executes and returns a single result. If no condition is met in the outer statement, CASE expression returns the value in the ELSE statement.
The SQL CASE ExpressionThe CASE expression goes through conditions and returns a value when the first condition is met (like an if-then-else statement). So, once a condition is true, it will stop reading and return the result. If no conditions are true, it returns the value in the ELSE clause.
After having a play with this, I have concluded that although the sequel gem aims to be be "simple, flexible and powerful", its syntax gets quite convoluted when things get a bit tricky.
Here is my best attempt at your query:
DB[:testtable].select(
Sequel.case([
[{code: 'a'}, 'x'],
[{code: ['m', 'n']}, 'y'],
[{class: ['p', 'q'], (Sequel.expr(:amount) > 0) => true}, 'z']],
nil).
as(:status)
)
This produces the following (almost correct) SQL:
SELECT (
CASE WHEN (`code` = 'a') THEN 'x'
WHEN (`code` IN ('m', 'n')) THEN 'y'
WHEN ((`class` IN ('p', 'q')) AND ((`amount` > 0) IS TRUE)) THEN 'z'
ELSE NULL END) AS `status` FROM `testtable`
I could not figure out how to use the inequality operator within a case statement. Maybe you'll have more luck with that.
My suggestion is that you just write the query in SQL, it will be significantly easier to read, and more maintainable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With