如何编写查询以获取每行最后n个元素的总和?

时间:2019-04-15 11:24:15

标签: mysql sql

我想为每一行计算数据库表中的最后N个元素的总和,我尝试了各种方法,但是我找不到任何方法可以在单个查询中做到这一点。

这就是我所拥有的,假设N为2,并且我有此数据,

day shop  sales
1    A    10
2    A    20  
3    A    30
4    A    40
5    A    50
1    B    100
2    B    200
3    B    300
4    B    400
5    B    500

我想要以下结果

day | shop | total sales of last 2 days
1     A       10
2     A       30 //sum of 10 and 20   
3     A       50 // sum of 20 and 30 
4     A       70  //sum of 30 and 40
5     A       90 // sum of 40 and 50
1     B       100
2     B       300
3     B       500
4     B       700
5     B       900

是否甚至可以在单个查询中执行此操作?

2 个答案:

答案 0 :(得分:2)

在MySQL 8+中,只需使用lag()

select t.*,
       (t.sales + lag(t.sales, 1, 0) over (partition by t.shop order by t.day)
       ) as two_day_sales
from t;

在旧版本中,使用left join

select t.*,
       (t.sales + coalesce(tprev.sales, 0)) as two_day_sales
from t left join
     t tprev
     on tprev.shop = t.shop and
        tprev.day = t.day - 1;

答案 1 :(得分:0)

我可以提出以下想法吗?

  • 获取sales排序的所有shop ASC, day ASC
  • 然后使用您的后端语言(我使用PHP),编写根据数组中的sales获得总计numberOfDays的代码。

这是PHP中的完整示例,但是您可以根据需要使用MySQL附带的任何语言:

$connection = mysqli_connect("localhost", "root", "", "database_test");

$sql_query = "
                SELECT *
                FROM table_sales
                ORDER BY shop ASC, day ASC
             ";

$result = mysqli_query($connection, $sql_query);

$numberOfDays = 3;
$daily_sales = array();
$total_sales = array();
$i = 0;

while($row = mysqli_fetch_array($result)) {

    $daily_sales[$i] = $row;
    $total_sales[$i] = $row;
    $total_sales[$i]["sales"] = 0;

    $offset = $i - $numberOfDays + 1;

    if($offset < 0)
        $offset = 0;

    for($j = $offset; $j <= $i; $j++) {
        if($total_sales[$i]["shop"] == $daily_sales[$j]["shop"])
            $total_sales[$i]["sales"] += $daily_sales[$j]["sales"];
    }

    $i++;
}

mysqli_close($connection);

$total_sales是一个多维数组。例如,您可以这样访问它:$total_sales[0]["sales"],它将为您提供numberOfDays中可以看到的特定商店的$total_sales[0]["shop"]的总销售额。

请记住要在MySQLi函数中进行错误处理,否则,如果不返回任何结果,则数组将为空。

如果您有任何疑问请发表评论,我会很乐意为您提供帮助。

编辑:我认为仅靠MySQL不可能实现您试图实现的目标,我也不认为应该这样做。这就是为什么我将PHP与MySQL相结合。

此外,根据您是否可能有成千上万的销售量,在大规模查询中检索所有销售结果可能不是一个好主意。作为解决方案,您可以根据特定商店检索它们。必须对代码进行的更改是,SQL必须看起来像这样:

SELECT *
FROM table_sales
WHERE shop = ?
ORDER BY day ASC

然后删除此行,因为它变得不必要:

if($total_sales[$i]["shop"] == $daily_sales[$j]["shop"])