Php 如何基于下一行中的值更新单个列

Php 如何基于下一行中的值更新单个列,php,sql,amazon-web-services,Php,Sql,Amazon Web Services,我有一个像这样的原始数据集 timestamp | eventtype | status | state | FinalState | Difference | -------------------------------------------------------------------------------| 12:00:56 PM | STATE_CHANGE | NULL | NULL | NULL | 00:00:0

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

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脚本中运行整个数据,但数据将是巨大的,可能会导致脚本超时,以供数百名用户运行

我认为在DB it内部运行这种数据操作是明智的。目前它被存储在AWS RDS中,因此它被存储在SQL中。但我不知道如何去做,也不知道这是否一个好的解决办法

你有没有想过如何以最有效的方式实现这一点

更新

在遵循提示表单的注释之后,我得到了这个查询的部分工作。我用serialnumber将数据移动到另一个表中

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;
但是我无法从子查询中获取数据。不断获取(null)作为结果。通过进一步的测试,看起来查询并没有将状态数据从第2行返回到第1行

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;

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

我找到了解决问题的方法。我将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链接在这里


我不知道该尝试什么。应该首先使用PHP脚本,或者调查数据库。您可以尝试类似的情况,当state=null时,然后选择status。从表中,serial_number=(serial number+1)作为正在进行的案例,将有一个特定的serail_编号,因此我们不需要遍历它,只需将此序列号增加到+1,以便返回下一行或-1上一行,然后使用子查询获取状态。。在查询中使用查询,并使用行号作为标识符跳转到上一行或下一行。我要试试这个。非常感谢。