我想为每一行计算数据库表中的最后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
是否甚至可以在单个查询中执行此操作?
答案 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
。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"])