mysql - 通过输入限制 sql 函数生成的行数

标签 mysql sql mariadb

尝试输出总损失金额(损失*金额)最低的行的总和,其中输入(数量)决定使用的行数,例如输入 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)

最佳答案

如果我没看错,您应该能够使用行号的不等式比较:

SELECT SUM(total) FROM cte WHERE row <= quantity;

例如,如果 quantity3,则上述查询将对前三行(最低)行的总计进行求和。

您从未提到过如果两个或多个总数平局会发生什么。在这种情况下,使用排名函数而不是行号可能更有意义。

编辑:

如果你想在 MySQL 中做同样的事情,你将不得不做更多的工作,因为它不支持任何内置的行号功能(尽管以后可能会支持)。为此,我们可以使用 session 变量来跟踪行号:

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;

这应该作为普通查询以及存储过程内部运行。如果您需要在函数内执行此操作,则可能需要实现一些微妙的游标工作,因为可能不支持 session 变量。它们可能不受支持的原因是,由于 session 变量的值可能会发生变化,给定相同的输入,函数不会始终返回相同的值。

关于mysql - 通过输入限制 sql 函数生成的行数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46950577/

相关文章:

php - 简单的 SQL UPDATE 查询使连接速度减慢 5-10 秒

mysql - 选择、求和、插入、如果存在则用 MySql 更新

sql - 缓慢的 MySQL 查询。我应该索引什么?

php - 如何编写 PHP 按钮来从数据库中选择行并运行 python 代码

mysql - 比较 MySQL 中的两个值

mysql - 尝试在 mysql 中创建过程时出现 RECURSIVE 附近的语法错误

mysql - 如何以正确的方式创建具有相似数据的表?

mysql - WordPress SELECT 和 JOIN 不起作用

mysql - 在多对多字段表关系中再次添加字段可以吗?

sql - 查找数据中的序列并按其分组