4

以下のSQLがあります

SELECT
ttstudent.ttstudentid,
ttstudent.studentid,
ttstudent.subjectid,
ttstudent.classnumber,
ttstudent.classid,
concat(student.fn, " ", student.sn) AS Student,
SUM(If(ondemand.cycle="Feb7" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr7 Feb`,
SUM(If(ondemand.cycle="Jul7" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr7 July`,
SUM(If(ondemand.cycle="Feb8" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr8 Feb`,
SUM(If(ondemand.cycle="Jul8" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr8 July`,
SUM(If(ondemand.cycle="Feb9" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr9 Feb`,
SUM(If(ondemand.cycle="Jul9" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr9 July`,
SUM(If(ondemand.cycle="Feb10" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr10 Feb`,
SUM(If(ondemand.cycle="Jul10" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr10 Aug`,
ondemand.Student_ID
FROM ttstudent
INNER JOIN student ON ttstudent.studentid = student.code
INNER JOIN ondemand ON ttstudent.studentid = ondemand.Student_ID
GROUP BY ondemand.Student_ID

これにより、約 25 人について、テーブルの最後の 2 つの値の差を見つける計算フィールドが最後の列である列形式のリストが生成されます。スコアはタイムスタンプ付きです。

CODE |Year7Feb|Year7Jul|Year8Feb|Year8Jul|Year9Feb|Year9Jul| Year10Feb| Growth
abe1 |    2.3 |   2.9  |        |        |        |        |          |   .6
bas1 |        |        |   3.5  |   3.7  |        |        |          |   .2
cod  |        |        |        |        |        |  4.5   |    5.2   |   .7

私がやりたいのは、各ユーザーから最後の 2 つのスコアを取得し (どちらの列にあるかに関係なく)、違いを見つける別の列を追加することです。私はこれを柱の成長と呼んでいます。

max以外に何を使おうか悩んでいます。何か案は?

4

1 に答える 1

6

これでうまくいくはずです:

growth次のクエリで列を計算します

SELECT si,ty,la.uid laid,pr.uid prid,(la.score-pr.score) growth FROM ( 
 SELECT si,ty,max(test_date) cyprev, cylast FROM ondemand INNER JOIN (
  SELECT Student_ID si,type ty,max(test_date) cylast FROM ondemand
         GROUP BY Student_ID,type
 ) od ON si=Student_ID AND ty=type AND cylast>test_date
 GROUP BY si,ty, cylast
) getlast2 
INNER JOIN ondemand la ON la.Student_Id=si AND la.type=ty AND la.test_date=cylast
INNER JOIN ondemand pr ON pr.Student_Id=si AND pr.type=ty AND pr.test_date=cyprev

次にLEFT JOIN、全体的なクエリに追加します(ここでは少し簡略化されたバージョン):

SET @subj:="Numeracy";
SELECT Student_id,
SUM(If(ondemand.cycle="Feb7" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr7 Feb`,
SUM(If(ondemand.cycle="Jul7" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr7 July`,
SUM(If(ondemand.cycle="Feb8" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr8 Feb`,
SUM(If(ondemand.cycle="Jul8" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr8 July`,
SUM(If(ondemand.cycle="Feb9" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr9 Feb`,
SUM(If(ondemand.cycle="Jul9" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr9 July`,
SUM(If(ondemand.cycle="Feb10" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr10 Feb`,
SUM(If(ondemand.cycle="Jul10" and ondemand.type=@subj, ondemand.Score, NULL)) AS `Yr10 Aug`,
growth
FROM ondemand LEFT JOIN (
 SELECT si,ty,la.uid laid,pr.uid prid,(la.score-pr.score) growth FROM ( 
  SELECT si,ty,max(test_date) cyprev, cylast FROM ondemand INNER JOIN (
   SELECT Student_ID si,type ty,max(test_date) cylast FROM ondemand
          GROUP BY Student_ID,type
  ) od ON si=Student_ID AND ty=type AND cylast>test_date
  GROUP BY si,ty, cylast
 ) getlast2 
 INNER JOIN ondemand la ON la.Student_Id=si AND la.type=ty AND la.test_date=cylast
 INNER JOIN ondemand pr ON pr.Student_Id=si AND pr.type=ty AND pr.test_date=cyprev
) gt ON si=Student_id AND ty=@subj  
GROUP BY Student_id;

JOINテーブルとその列の s を省略studentttstudentました

ttstudent.ttstudentid,
ttstudent.studentid,
ttstudent.subjectid,
ttstudent.classnumber,
ttstudent.classid,
concat(student.fn, " ", student.sn) AS Student

編集:

test_date列を使用して変更を加えました。サブクエリは MySQL でテストされました。データベースでも動作することを願っています。

編集2:

私はあなたがどこから来ているかをゆっくりと見ています。ますます複雑になっています (追加の条件を入力しただけtype="Numeracy"です... 結局のところ、より簡単な解決策があるのでしょうか?

とにかく、ここにすべてを示すSQLfiddleがあります (ここでは修正版: sqlfiddle2 )。

3回目と最後の編集:

おそらく必要なのは、 SQLfiddle3の行にあるものです(-->前のステートメントのない1 つのSELECT コマンドのみ)。SET完全なコマンドは次のようになります。

SELECT
ttstudent.ttstudentid,
ttstudent.studentid,
ttstudent.subjectid,
ttstudent.classnumber,
ttstudent.classid,
concat(student.fn, " ", student.sn) AS Student,
SUM(If(ondemand.cycle="Feb7" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr7 Feb`,
SUM(If(ondemand.cycle="Jul7" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr7 July`,
SUM(If(ondemand.cycle="Feb8" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr8 Feb`,
SUM(If(ondemand.cycle="Jul8" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr8 July`,
SUM(If(ondemand.cycle="Feb9" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr9 Feb`,
SUM(If(ondemand.cycle="Jul9" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr9 July`,
SUM(If(ondemand.cycle="Feb10" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr10 Feb`,
SUM(If(ondemand.cycle="Jul10" and ondemand.type="Numeracy", ondemand.Score, NULL)) AS `Yr10 Aug`,
ondemand.Student_ID,
getdif.growth
FROM ttstudent
INNER JOIN student ON ttstudent.studentid = student.code
INNER JOIN ondemand ON ttstudent.studentid = ondemand.Student_ID
LEFT JOIN (
 SELECT si,ty,la.uid laid,pr.uid prid,(la.score-pr.score) growth FROM ( 
  SELECT si,ty,max(test_date) cyprev, cylast FROM ondemand INNER JOIN (
   SELECT Student_ID si,type ty,max(test_date) cylast FROM ondemand
          GROUP BY Student_ID,type
  ) od ON si=Student_ID AND ty=type AND cylast>test_date
  GROUP BY si,ty, cylast
 ) getlast2 
 INNER JOIN ondemand la ON la.Student_ID=si AND la.type=ty AND la.test_date=cylast
 INNER JOIN ondemand pr ON pr.Student_ID=si AND pr.type=ty AND pr.test_date=cyprev
) getdif ON si=ondemand.Student_ID AND ty=ondemand.type
WHERE ondemand.type='Numeracy'
GROUP BY ondemand.Student_ID

私の以前のバージョンは、あらゆる種類の冗長性を回避するという私の個人的な好みと、物事を可能な限りパラメータ化するという私の野心を反映していました。しかし、私はおそらく少し行き過ぎました;-)。

于 2013-08-03T11:57:14.433 に答える