尝试输出具有最低总损失金额(丢失*金额)的行的总和,其中输入(数量)确定所使用的行的数量,例如,输入3返回最低3行的总和。 使用MariaDB,当前代码为:
DELIMITER ++
CREATE FUNCTION TotalLoss (quantity INT) returns INT
WITH cte AS (
SELECT
M.lost*C.Number AS total,
ROW_NUMBER() OVER (ORDER BY M.Lost*C.Number) AS row
FROM Money M
JOIN Company C
ON M.Id = C.MId
)
SELECT SUM(total) FROM cte WHERE row = quantity;
DELIMITER ;
TABLE Money (Id, lost) has values (1, 10), (2,40), (3,90), (4,100)
Table Company (MId, Number) has values (3, 4), (1,2), (5, 1), (4,1)
给定输入2,输出将为220
由于最低的两个是(10 * 2 + 100 * 2)
答案 0 :(得分:0)
如果我读得正确,你应该只能使用行号的不等式比较:
SELECT SUM(total) FROM cte WHERE row <= quantity;
例如,如果quantity
为3
,则上述查询将汇总前三(最低)行的总数。
你从未提及在两个或两个以上的总数相关的情况下会发生什么。在这种情况下,使用排名函数而不是行号可能更有意义。
修改强>
如果你想在MySQL中做同样的事情,你将不得不做更多的工作,因为它不支持任何内置的行号功能(虽然它可能在以后)。为此,我们可以使用会话变量来跟踪行号:
SELECT SUM(total)
FROM
(
SELECT
(@rn:=@rn + 1) AS rn,
M.lost*C.Number AS total
FROM Money M
INNER JOIN Company C
ON M.Id = C.MId
INNER JOIN (@rn:=0) t
ORDER BY
total
) t
WHERE
t.rn <= 3;
这应该作为普通查询以及存储过程内部运行。如果您需要在函数内执行此操作,则可能需要实现一些精细的游标工作,因为可能不支持会话变量。它们可能不受支持的原因是,由于会话变量的值可能会发生变化,函数在给定相同输入的情况下不会始终返回相同的值。