Как обновить один столбец на основе значений в следующей строке - PullRequest
0 голосов
/ 08 декабря 2018

У меня есть набор необработанных данных, который выглядит следующим образом

timestamp   | eventtype    | status    | state      | FinalState | Difference  |
-------------------------------------------------------------------------------|
12:00:56 PM | STATE_CHANGE | NULL      | NULL       | NULL       | 00:00:00    |
12:01:39 PM | STATE_CHANGE | Available | CONNECTING | NULL       | 00:00:00    |

Чтобы выполнить некоторые отчеты о состоянии пользователя, мне нужно обновить FinalState, а затем рассчитать разницу во времени между четными типами, используя отметку времени.

Это логика, которой необходимо следовать для обновления FinalState

IF currentrow_state == null 
    IF currentrow_status == NULL 
        return available
    ELSE nextrow_status
ELSE IF ( currentrow_state == NULL OR currentrow_state == ENDED)
        IF previousrow_state == currentrow_state 
            return nextrow_status
        ELSE
            return currentrow_state
    ELSE
        return currentrow_state 

Я не совсем понимаю, как выполнить эту операцию.Я думаю, что это может быть сделано в скрипте PHP, чтобы пройти через все данные, но данные будут огромными и могут привести к тому, что время ожидания скрипта будет работать для сотен пользователей.

Я думал, что это будетразумно запускать эти манипуляции с данными внутри самой БД.В настоящее время он хранится в AWS RDS, поэтому он находится в SQL.Но я не могу понять, как это сделать, и не знаю, является ли это хорошим решением.

Есть какие-нибудь мысли о том, как это можно сделать наиболее эффективным способом?

Обновление

После следования подсказке к комментарию я получил этот запросчастично работает.Я переместил данные в другую таблицу с серийным номером

SELECT serialnumber,timestamp,username,status,state,
    CASE 
        WHEN state = 'NULL' 
            THEN (CASE 
                        WHEN status = 'NULL' 
                        THEN "Available"
                  ELSE (SELECT status FROM ATEMP WHERE  state IS NULL AND status IS NOT NULL AND serialnumber=1)
                  END) 
            ELSE (CASE 
                        WHEN state = 'NULL' OR state LIKE 'ENDED' 
                        THEN (SELECT status FROM ATEMP WHERE  state IS NULL AND status IS NOT NULL AND serialnumber=1)
                        ELSE state
                        END)
            END as finalvalue
FROM ATEMP;

Но я не могу получить данные из подзапроса.Сохраняет (ноль) как результаты.После еще нескольких испытаний не похоже, что запрос возвращает данные о состоянии из строки 2 в строку 1

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Я нашел решение своей проблемы.Я обновил MYSQL до MYSQL 8 и использовал две функции LEAD и LAG и концепцию под названием WINDOW, о которой мне еще только предстоит узнать.

И затем этот запрос чудесным образом

Select * FROM (
SELECT serialnumber,timestamp,username,status,state,
    CASE 
        WHEN state = '' 
            THEN (CASE 
                        WHEN status = '' 
                        THEN "Available"
                  ELSE LEAD(status) over w
                  END) 
            ELSE (CASE 
                        WHEN state = '' OR state LIKE 'ENDED' 
                        THEN (CASE 
                                    WHEN state = LAG(state) over w
                                    THEN LEAD(status) over w
                                    ELSE state
                                END) 
                        ELSE state
                        END)
            END as FinalState
FROM ATEMP window w as (order by serialnumber)) a order by timestamp,FinalState DESC ;

Надеюсь, это поможет любому, кто ищет подобную функцию.

Ссылка MYSQL здесь

https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html

0 голосов
/ 08 декабря 2018
SELECT CASE 
               WHEN STATE IS NULL
                 THEN 
                (
               CASE WHEN STATUS=NULL
                THEN "AVAILABLE"
                ELSE
                (SELECT STATUS FROM TABLE WHERE  STATE
                 IS NULL AND STATUS IS NOT NULL AND 
                   ROWNUM=1)
               END CASE  )

               WHEN STATE IS NULL OR STATUS LIKE 
              "ENDED" THEN

                 (
               CASE WHEN
                  STATE= (SELECT STATE FROM TABLE 
                   WHERE  ROWNUM=ROWNUM-1)
                   THEN 
                                     STATE

             )
                ELSE
                (SELECT STATUS FROM TABLE WHERE  STATE
                 IS NULL AND STATUS IS NOT NULL AND 
                   ROWNUM=1)
               END CASE  )

     )
     ELSE 
            (SELECT STATE FROM TABLE WHERE  STATE
                 IS NULL AND STATUS IS NOT NULL AND 
                   ROWNUM=1)
         END CASE FROM TABLE;

Вы можете обойтись настройкой case для каждого if, поскольку я не могу полностью выяснить, чтобы определить следующую строку или предыдущее состояние / состояние строки на основе ваших столбцов в качестве идентификатора в подзапросе.Можете попробовать выше в качестве шаблона.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...