我有一个看起来像这样的原始数据集
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
答案 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,并使用了两个功能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