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 テーブルには「本質的な」順序はないため、その「until」句に何らかの意味を与えるには、ORDER BY 句を指定する必要があります。それを考えると、「最初の」 N 個のレコードの合計は、SELECT SUM(money) FROM student ORDER BY xxx LIMIT N で取得できます。自然順序の整数を持つ補助テーブル INTS を使用すると、適切な最大値を見つけることができます。 N 次のようなものによって:

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

最後に、全体的な SELECT の LIMIT 句の別のネストされた SELECT としてこれを挿入します。しかし、これはすべて効率が悪いように思えます。入れ子になった 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 に答える