2016-12-29 10 views
0

для анализа данных проекта мне нужно разделить таблицу в отношении датированного табеля работника в следующем формате:Mysql определяемого пользователя переменный не обновляется, когда 0

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

Для двух колонок я использую USER- определенной переменной @cur_Count в операторе CASE.

... 
(
    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 
    ... 

Это утверждение отлично работает - с небольшим исключением того, что (так как @cur_Count сбрасывается на 1 в предложении ELSE) первая запись для сотрудника начать с 7-й день вместо 0.
Однако, если Я использую один из следующих

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

или сбросить переменную 0 любым другим способом, то результат выглядит следующим образом:

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

S o очевидно, что переменная игнорирует любую попытку обновить ее значение после сброса на 0. В то время как эту проблему легко обойти, она все еще озадачивает (и обходной путь не является аккуратным). Я что-то упустил здесь или это ошибка MySql?

Заранее благодарим за любые отзывы!

+0

где вы инициализировать переменную. вы можете показать полное заявление? вы можете добавить ** CROSS JOIN (SELECT @cur_Count: = 0) в качестве init ** для этого –

+0

@ Bernd Buffen Я добавил инициализацию к сообщению выше. – Markus

ответ

0

Переключить порядок выражения AND к

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

Это потому, что AND выполняет короткое замыкание. Когда вы назначаете 0, это обрабатывается как FALSE, поэтому он не выполняет задание.

Другим вариантом было бы вычитать 7 после умножения:

(
    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, 
+0

Ах, я не знал, что ': = 0' рассматривается как' FALSE'. Это объясняет проблему. К сожалению, изменение порядка в предложении 'ELSE' не решает его, и, по крайней мере, сейчас я не могу представить другого способа структурирования запроса. Обходной путь, который вы описали, в значительной степени является решением, которое я использовал до сих пор. Наверное, мне придется придерживаться этого момента. Большое спасибо! – Markus

+0

Я играю с заявлением 'CASE' и столкнулся с еще более странным поведением. С 'ELSE @cur_Employee: = e.EMPLOYEE AND @cur_Count: = 1 переменная также не обновляется. С помощью 'ELSE (@cur_Employee: = e.EMPLOYEE AND @cur_Count: = 1 AND @cur_Count: = @cur_Count - 1 переменная чередуется между значениями' 0' и '1', независимо от того, выполнено ли условие' CASE' или нет. По-видимому, есть некоторые аспекты 'CASE', которые я не совсем понимаю (порядок выполнения?). Официальная документация не разъясняет это для меня, знаете ли вы о каких-либо хороших источниках по этой теме? – Markus

+0

Проблема что 'AND' имеет более высокий приоритет, чем': = ', поэтому он рассматривает его как' @cur_Employee: = (e.employee AND (@cur_count: = 0)). Я добавил круглые скобки, чтобы переопределить это. – Barmar

 Смежные вопросы

  • Нет связанных вопросов^_^