これが、1つのステートメントですべてを実行する方法です。(このクエリはidtanklevel
、テーブル内のPRIMARYKEYまたは少なくともUNIQUEKEYであると想定していることに注意してtanklevel2
ください。そうでない場合は、クエリを調整する必要があります。)
各テーブル参照と各インラインビューの目的を文書化するための簡単なコメント:
-- m = get id of latest row
-- t = get latest row (the row to be updated)
-- pr = get id for the prior row
-- pri = source for prior row id
-- l = id of latest row (identical to "m")
-- pv = get value from prior row
-- p = wrapper so we can join to row returned from pv
UPDATE fw_db.tanklevel2 t
JOIN ( SELECT MAX(idtanklevel) AS idtanklevel FROM fw_db.tanklevel2 ) m
ON m.idtanklevel = t.idtanklevel
CROSS
JOIN ( SELECT pv.glycolsmall
, pv.idtanklevel
FROM ( SELECT MAX(pri.idtanklevel) AS idtanklevel
FROM fw_db.tanklevel2 pri
WHERE pri.idtanklevel <
(SELECT MAX(l.idtanklevel) FROM fw_db.tanklevel2 l)
) pr
JOIN fw_db.tanklevel2 pv
ON pv.idtanklevel = pr.idtanklevel
LIMIT 1
) p
SET t.glycolsmallchange = ROUND(t.glycolsmall - p.glycolsmall,2)
上記のクエリでは、「前の」行を識別するために少し異なる手法を使用していることに注意してください。クエリは、最大ID値から1を引くのではなく、2番目に高いID値(最大値よりも低い最大ID値)を取得します。
クエリが使用しているのと同じ戦略を実装するには(つまり、最大ID値から1を引くには、上記のクエリのこの部分を削除します。
FROM ( SELECT MAX(pri.idtanklevel) AS idtanklevel
FROM fw_db.tanklevel2 pri
WHERE pri.idtanklevel <
(SELECT MAX(l.idtanklevel) FROM fw_db.tanklevel2 l)
) pr
これに置き換えます:
FROM ( SELECT MAX(l.idtanklevel)-1 AS idtanklevel
FROM fw_db.tanklevel2 l
) pr
このステートメントをテストするには、実際に更新を実行せずに、句を削除し、キーワードを、返される行を確認できる関連する式のリストにSET
置き換えます。例:UPDATE
SELECT
SELECT t.glycolsmallchange AS old_glycolsmallchange
, ROUND(t.glycolsmall - p.glycolsmall,2) AS new_glycolsmallchange
, t.idtanklevel AS latest_row_id
, t.glycolsmall AS latest_glycolsmall
, p.idtanklevel AS prior_row_id
, p.glycolsmall AS prior_glycolsmall
FROM