0
@x=0
select
  case
    when col>1 then @x:=@x+1
    when col=1 then @x
    else @x; @x:=@x+1
  end as x
from t

I want to do something like what's seen above in MySQL. The contents between the WHEN and THEN are arbitrary. However, what I want to do is seen after the ELSE statement. I know I can set a user variable where I can either output its value in the SELECT (by just using @x), or output some updated value (by using @x:=@x+1). What I want to do though is output the value @x, while also updating it @x:=@x+1. Is this possible?

4
  • You can do this with a stored procedure by first recording the current value, then performing the operation, then returning the stored value 🤔
    – matigo
    Commented Sep 4, 2021 at 0:05
  • @matigo Sorry I'm doing this for Hackerrank, since I'm practicing for interviews and they don't seem to allow stored procedures with MySQL.
    – yqz09
    Commented Sep 4, 2021 at 0:22
  • I suppose user functions are out too, because that would be relatively straight forward.
    – danblack
    Commented Sep 4, 2021 at 0:46
  • @variable := ... inside a SELECT is likely to be disallowed in future versions of MySQL. Already it wreaks havoc with Optimizations. And vice versa.
    – Rick James
    Commented Sep 4, 2021 at 6:51

2 Answers 2

2

CASE statement and CASE operator don't behave the same way. In a SELECT, it's the CASE operator. Each when/then and the else can only contain one expression returning 1 result. On the other hand, the CASE statement behaves like in other languages, where each conditions can have a block of code of any length.

Also, even if this syntax was possible, there is a big risk to do something like this. There is no guarantee at all in which order records will be processed, so the result could be totally different from one execution to another.

You may think adding a ORDER BY will solve this problem. But, since ORDER BY is the last section of the SELECT statement to be executed, the calculation would be done before the rows are sorted anyway.

3
  • I'm applying it to a subquery which is ordered correctly so I don't think I need to be worried about this issue. Thanks though.
    – yqz09
    Commented Sep 4, 2021 at 0:30
  • 1
    Ok. What if you try this: @x=0 select case when col>1 then @x:=@x+1 when col=1 then @x else (@x:=@x+1)-1 end as x from t Commented Sep 4, 2021 at 0:40
  • Prevost, awesome! You've solved my problem. I was trying so hard to think of a simple trick like this, and you helped me find it. Thanks a million!
    – yqz09
    Commented Sep 4, 2021 at 0:46
0

The case expression needs to return a single value. To get another @x include it as a separate SELECT result like:

select
  @x,
  case
    when seq>2 then @x:=@x+1
    when seq=1 then @x
    else @x:=@x+1
  end as x
from seq_0_to_10

ref: fiddle

1
  • Interesting idea, but I'm still looking for it to output the single @x value while simultaneously updating it before moving on to the next row. Otherwise, the iterator becomes meaningless within the logic of my CASE expression.
    – yqz09
    Commented Sep 4, 2021 at 0:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.