2013-02-08 102 views
1

这可能是一个梦想,但我试图让这两个单独工作的命令作为一个单一命令来工作。而不是XXXXX,我想倾倒在选择语句(这给了我昨天的总数和今天的总数的差异)。组合命令将查找最近的行(max idtanklevel),并用它自己和前一行的差异来更新它。Mysql将max id的行更新为sum语句的值

update fw_db.tanklevel2 T3 
inner join (select max(idtanklevel) as idtanklevel from fw_db.tanklevel2) T4 
on T3.idtanklevel = T4.idtanklevel 
set glycolsmallchange = XXXXX; 

select round(sum((T1.glycolsmall) - (T2.glycolsmall)),2) 
from fw_db.tanklevel2 T1, fw_db.tanklevel2 T2 
where 
T1.idtanklevel = (select max(idtanklevel) from fw_db.tanklevel2) 
and 
T2.idtanklevel=(select max(idtanklevel)-1 from fw_db.tanklevel2); 

在此先感谢。

+1

问:'idtanklevel'的PRIMARY KEY或在'tanklevel2'表的唯一键? – spencer7593 2013-02-08 20:53:51

+1

另外,我不确定'max(idTankLevel) - 1'是否会获得_previous_条目。这就要求'idTankLevel'严格单调,并且_guaranteed_总是要写 - 如果事务回滚,那么可能不是真的。可惜这是mySQL,没有像ROW_NUMBER()这样的东西......虽然我认为在这种情况下可以作弊。你能告诉我们开始/结果数据吗?哦,表格是否有一个日期/时间/时间戳列可用于排序? – 2013-02-08 21:09:03

+0

如果'idtanklevel'是'tanklevel2'表中的PRIMARY KEY或UNIQUE KEY,那么在第二个查询中就不需要SUM [聚合] ...也就是说,可以通过查询来获得该结果没有“SUM”聚合。 – spencer7593 2013-02-08 22:32:30

回答

0

下面是我将如何在单个语句中完成所有工作。 (请注意,此查询假设idtankleveltanklevel2表的主键或至少一个唯一的密钥;查询将需要调整,如果事实并非如此)

一些简短的评论记录各自的用途表参考,并且每个线视图:

-- 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值(最高的id值低于最大值),而不是从最大的id值中减去1。

为了实现您的查询使用相同的策略(即从值的最大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 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 
+0

工作就像一个魅力,谢谢斯宾塞! – 2013-02-09 00:12:39