与前一行的mysql百分比差异

时间:2014-05-24 05:00:47

标签: mysql sql

如何计算mysql中每一行的%差异?

我能够让它工作,但如果我的date列不连续,我不确定如何动态拉动它:

SELECT c1.date, 
       c1.total, 
       ( ( c1.total - ifnull(c2.total, 0) ) / c1.total ) AS percentage_change 
FROM   table c1 
       LEFT OUTER JOIN table c2 
                    ON c1.id = c2.id 
                       AND c1.date - c2.date = 1 
ORDER  BY c1.date DESC 
LIMIT  30 

问题在于我的date列不一定是c1.total - c2.total = 1

我刚才有一个想法是做一个子查询和select where c2.date < c1.date order by c2.date DESC LIMIT 1。我认为这将选择下一个最低的日期值,所以现在就尝试。

2 个答案:

答案 0 :(得分:2)

以下是如何做到的:

SELECT current.id, current.date, ((current.total - IFNULL(prev.total, 0)) / current.total) AS percentage_change
FROM
(SELECT c1.id, c1.total, count(c2.*) as ordinal
FROM some_table AS c1, some_table AS c2
WHERE c2.date < c1.date) AS curr

OUTER JOIN (SELECT c1.id, c1.total, count(c2.*) as ordinal
FROM some_table AS c1, some_table AS c2
WHERE c2.date < c1.date) AS prev
    ON curr.ordinal - 1 = prev.ordinal;

假设您没有任何具有相同日期的行(假设我的语法中没有任何拼写错误),这将有效。但是,如果可以避免,我会建议不要这样做。

我首选的解决方案是使用它(更有效的查询):

SELECT * FROM some_table ORDER BY date ASC;

然后在迭代结果集时在应用程序内部进行数学计算(无论是什么)。

答案 1 :(得分:0)

这是我的尝试,并非100%确定它是否有效并且好奇如果没有使用3个表更好的方法

SELECT c1.date, 
       c1.total, 
       ( ( c1.total - Ifnull((SELECT c3.date 
                              FROM   table c3 
                              WHERE  c3.date < c1.date 
                              ORDER  BY c3.date DESC 
                              LIMIT  1), 0) 
                       ) / c1.total ) AS percentage_change 
FROM   table c1 
       LEFT OUTER JOIN table c2 
                    ON c1.id = c2.id 
                       AND c1.date - c2.date = 1 
ORDER  BY c1.date DESC 
LIMIT  30