如何根据下一行中的值更新单列

时间:2018-12-07 21:10:13

标签: php sql amazon-web-services

我有一个看起来像这样的原始数据集

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;

但是我无法从子查询中获取数据。不断获得(空)作为结果。经过更多测试,查询似乎没有从row2返回状态数据到row1

2 个答案:

答案 0 :(得分:0)

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;

您可以为每个if设置大小写,因为我无法完全根据您的列作为子查询中的标识符来确定下一行或上一行的状态/状态。可以尝试以上作为模板。

答案 1 :(得分:0)

我找到了解决问题的方法。我将MYSQL升级到MYSQL 8,并使用了两个功能LEADLAG以及一个名为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