2017-02-10 19 views
0

私は、このコードはもっとうまくいくと信じる理由があります。SQL:選択クエリの改善

私はこれを説明しようとします。

私のデータベースの各行には、exerciseの1,2または3のいずれかの値があり、さらに数字としてrepという数字がありますが、このコードでは1〜12しか気にしませんコードは、(列であり、各行に値を持つ)の最高値を持つ行を選択します。exerciseは1で、repは1、次に2と3などなどは12まで、次にexerciseを2を選択し、1-12から再びkilograms行を選択します。

これは意味がありますか?

for (var i = 1; i <= 3; i++) { 
    for (var ii = 1; ii <= 12; ii++) { 
     var getPR = "SELECT top 1 kg, rep, date FROM Test WHERE exerVariName = 'Comp' AND exercise = @0 AND rep = @1 order by kg desc"; 
     db.Execute(getPR, i, ii); 
     foreach (var get in db.Query(getPR, i, ii)) { 
      DateTime Date = get.Date; 
      var finalDate = Date.ToString("MMM d, yyyy"); 
      var weight = get.kg + "kg"; 
      var reps = "x " + get.rep; 
      <a>@weight @reps - @finalDate</a> 
      <br> 
     } 
    } 
} 

私はSQL Server Compactを使用しています。これはMVCプロジェクトではありません。

+0

これはCSHTMLファイルの一部であり、言わないでください? – trailmax

+0

なぜですか? @trailmax –

+0

Razorファイルは、ビューモデルデータをHTMLマークアップに適用するために作成されます。 DBリクエストはコントローラ内に存在し、データとともにビューモデルを渡す必要があります。 (MVCと仮定) – trailmax

答えて

3

Group ByMAX集約関数を使用して、1つのクエリで対象のすべての行を選択できます。

SELECT t.kg, t.rep, t.date 
FROM Test t 
INNER JOIN 
    (SELECT MAX(kg) as kg, exercise, rep 
    FROM Test 
    WHERE exerVariName = 'Comp' 
    GROUP BY exercise, rep) i 
ON t.exercise = i.exercise AND t.rep = i.rep AND t.kg = i.kg 
WHERE t.exerVariName = 'Comp' 

内部クエリは1回だけ実行されます。グループ識別子(exercise, rep)タプルと対応する最大値kgのグループ値が見つかります。 次に、内部クエリはTestテーブルと結合され、行の "内容"を取得します(あなたのケースでは1つの追加フィールドdate)。

全体のパフォーマンスは最適化されません。

このクエリの結果を繰り返し処理するだけで済みます。

this topicを参照してください。


編集:

が同じkg(OPのループとほぼ同じ結果)を有する複数の(rep, exercise)レコードを除外

SELECT kg, rep, exercise, MAX(date) 
FROM 
    (SELECT t.kg, t.rep, t.exercise, t.date 
    FROM Test t 
    INNER JOIN 
     (SELECT MAX(kg) as kg, exercise, rep 
     FROM Test 
     WHERE exerVariName = 'Comp' 
     GROUP BY exercise, rep) i 
    ON t.exercise = i.exercise AND t.rep = i.rep AND t.kg = i.kg 
    WHERE t.exerVariName = 'Comp') t 
GROUP BY t.kg, t.rep, t.exercise 
+0

私はこれらを今すぐテストしていますが、コードを理解できないので結合についてもっと知る必要があることがわかります。これらの2つの異なるクエリは異なるものをもたらしますが、後のものは行の量の半分のように表示されますが、どちらが正しいものなのかよくわからないので、私は '運動 'もループしたいあなたがそれを手助けしたいのであれば、それが正しいかどうかを決定するものは何ですか? –

+0

Okeyなので、エクササイズナンバーを表示して、それを私の古いクエリー/ forループコードの結果と比較することができました。そして、 'exercise'が2または3であればすべて正しい結果を得ました。私のクエリが示した6つの結果のうち4つは、理由を理解できません:/ –

+0

* 'my query' *はあなたについて話していますか?私は 'getPR'クエリが最大で1つの結果を返すことがわかります。あなたはあなたのクエリが返されたと言います。 –

0
SELECT kg, rep, date, exercise, rep FROM Test test1 WHERE rep = (SELECT TOP 1 test2.rep FROM Test test2 WHERE test2.exercise = test1.exercise AND test2.rep = test1.rep ORDER BY kg DESC) GROUP BY exercise, rep 

これらの結果をループして表示します。

+0

この結果、「クエリの解析中にエラーが発生しました。 [トークン行番号= 1、トークン行オフセット= 66、トークンエラー= SELECT] ' –