Search code examples
mysqlinnodb

Mysql user-defined variable not updating when 0


for a data analysis project I need to split up a table concerning dated employee timesheets in the following format:

Employee|Start_Days|End_Days|...
0001|0|7|...
0001|7|14|...
0001|14|21|...
0002|0|7|...
0002|14|21|...
...  

For the two columns I am using a user-defined variable @cur_Count in a CASE statement.

...
(
    CASE 
        e.EMPLOYEE
    WHEN
        @cur_Employee
    THEN
        @cur_Count := @cur_Count + 1
    ELSE
        @cur_Count := 1
        AND @cur_Employee   := e.EMPLOYEE
    END
) * 7 AS START_DAYS,
(@cur_Count + 1) * 7 AS END_DAYS,
...
FROM 
    tmp_MS_Relevant_Employees AS e, 
    hlp_MS_Calendar_Weeks AS c,
    (SELECT @cur_Employee = '', @cur_Count := 0) AS init
WHERE
    ...

This statement works perfectly fine - with the little exception that (since @cur_Count is reset to 1 in the ELSE clause) the first entry for an employee start with day 7 instead of 0.
However, if I use one of the following

@cur_Count := 0 
@cur_Count := @cur_Count * 0
@cur_Count := @cur_Count - @cur_Count

or reset the variable to 0 in any other way, the output looks like this:

Employee|Start_Days|End_Days|...
0001|0|7|...
0001|0|7|...
0001|0|7|...

So apparently the variable ignores any attempt to update its value once it is reset to 0. While this issue is easy to work around, it is still puzzling (and the workaround isn't tidy). Am I missing something here or is this a bug of MySql?

Thanks in advance for any feedback!


Solution

  • Switch the order of the AND expression to

        (@cur_Employee := e.EMPLOYEE)
        AND (@cur_Count := 0)
    

    This is because AND performs short-circuiting. When you assign 0, that's treated as FALSE, so it doesn't perform the assignment.

    Another option would be to substract 7 after multiplying:

    (
        CASE 
            e.EMPLOYEE
        WHEN
            @cur_Employee
        THEN
            @cur_Count := @cur_Count + 1
        ELSE
            (@cur_Count := 1)
            AND (@cur_Employee   := e.EMPLOYEE)
        END
    ) * 7 - 7 AS START_DAYS,