8

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

假设你要选择学生,直到学生的钱总和达到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。

4

3 回答 3

5

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

    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;
于 2011-07-26T20:18:45.100 回答
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 看起来太多且太慢时,另一种方法是逐步执行此操作:首先使用“渐进总和”构建一个临时表,然后使用它来帮助您找到所需的限制。

于 2009-05-08T13:17:57.787 回答
1

糟糕... 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 排序——索引扫描将成为最昂贵的操作。

于 2009-05-08T14:27:28.917 回答