【问题标题】:Sum until certain point - MySql总和直到某个点 - MySql
【发布时间】:2009-05-08 13:05:11
【问题描述】:

如何查询和显示记录直到达到一定数量?

假设你要选择学生,直到学生的钱总和达到1000?

加法

 Student ID   Student Name   Student Money 
 ---------    -----------     --------------
   1           John            190
   2           Jenny           290
   3           Ben             200
   4           Andy            120
   5           Lynna           300

如果我想停在 500,我会得到记录号 1 和 2 (190 + 290)。 如果我想停在 1000,我会得到记录 1 到 4。

【问题讨论】:

    标签: mysql sum


    【解决方案1】:

    在寻找我自己的答案时遇到了这个问题。我想我会把我的解决方案留在这里,因为它是完成相同任务的另一种方式,并且可能更有效。诀窍是使用>= 进行自我加入

        SELECT s1.ID, s1.name, s1.money, sum(s2.money) as accumulator
        FROM student s1 
        INNER JOIN student s2 ON s1.id >= s2.id 
        GROUP BY s1.id HAVING accumulator <= 500;
    

    【讨论】:

      【解决方案2】:

      SQL 表没有“内在”顺序,因此您必须指定一些 ORDER BY 子句以赋予“直到”短语任何含义。鉴于此,可以使用 SELECT SUM(money) FROM student ORDER BY xxx LIMIT N 获得“第一”N 条记录的总和。使用具有自然顺序整数的辅助表 INTS,您可以找到最合适的N 类似于:

      SELECT MAX(N) FROM INTS
      WHERE (SELECT SUM(money) FROM student ORDER BY xxx LIMIT N) < 1000
      

      最后将它作为另一个嵌套 SELECT 插入到整个 SELECT 中的 LIMIT 子句中。不过,所有这些闻起来都会相当低效!通常,当嵌套的 SELECT 看起来太多且太慢时,另一种方法是逐步执行此操作:首先使用“累进总和”构建一个临时表,然后使用它来帮助您找到所需的限制。

      【讨论】:

      • 我认为 LIMIT N 只会限制记录数,它可以限制总和本身吗?
      • 对,WHERE (SELECT SUM ...)
      • 例如,对于您现在添加的表示例,辅助表可以由 SELECT S1.Id, SUM(S2.Money) FROM Student S1, Student S2 WHERE S2.Id &lt;= S1.Id 构建(按 Id 隐式排序)。
      【解决方案3】:

      糟糕... MySQL ...此解决方案适用于 MS SQL ...

      这是使用 ROW_NUMBER() 函数的解决方案。

      SELECT Student.*, SUM(StudentBefore.Money) AS AccumulatedMoney  
      FROM (  
             SELECT *, ROW_NUMBER() OVER(ORDER BY Id) AS RowNumber  
             FROM Students  
           ) AS Student  
           INNER JOIN  
           (  
             SELECT *, ROW_NUMBER() OVER(ORDER BY Id) AS RowNumber  
             FROM Students  
           ) AS StudentBefore  
           ON StudentBefore.RowNumber <= Student.RowNumber  
      GROUP BY Student.RowNumber, Student.Id, Student.Name, Student.Money  
      HAVING SUM(StudentBefore.Money) < 1000  
      

      执行计划表明排序表是最昂贵的操作。如果要排序的列上有索引 - 您的示例表明您要按主键 id 排序 - 索引扫描将成为最昂贵的操作。

      【讨论】:

        猜你喜欢
        • 2020-12-24
        • 1970-01-01
        • 1970-01-01
        • 2018-11-17
        • 1970-01-01
        • 1970-01-01
        • 2018-02-24
        • 2021-12-16
        • 1970-01-01
        相关资源
        最近更新 更多